mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-11 03:58:14 +00:00
(improvement) Move out the datasource and merge the datasource with the model, and adapt the chat module (#423)
Co-authored-by: jolunoluo <jolunoluo@tencent.com>
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
package com.tencent.supersonic.semantic.api.model.pojo;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Data
|
||||
public class DatasourceDetail {
|
||||
public class ModelDetail {
|
||||
|
||||
private String queryType;
|
||||
|
||||
@@ -19,5 +21,11 @@ public class DatasourceDetail {
|
||||
|
||||
private List<Measure> measures;
|
||||
|
||||
public String getSqlQuery() {
|
||||
if (StringUtils.isNotBlank(sqlQuery) && sqlQuery.endsWith(";")) {
|
||||
sqlQuery = sqlQuery.substring(0, sqlQuery.length() - 1);
|
||||
}
|
||||
return sqlQuery;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.api.model.request;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DatasourceRelaReq {
|
||||
|
||||
private Long id;
|
||||
|
||||
@NotNull(message = "model id cat not be null")
|
||||
private Long modelId;
|
||||
|
||||
@NotNull(message = "datasource id cat not be null")
|
||||
private Long datasourceFrom;
|
||||
|
||||
@NotNull(message = "datasource id cat not be null")
|
||||
private Long datasourceTo;
|
||||
|
||||
@NotNull(message = "join key cat not be null")
|
||||
private String joinKey;
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.api.model.request;
|
||||
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.DimensionTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Dim;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
||||
@Data
|
||||
public class DatasourceReq extends SchemaItem {
|
||||
|
||||
private Long databaseId;
|
||||
|
||||
private String queryType;
|
||||
|
||||
private String sqlQuery;
|
||||
|
||||
private String tableQuery;
|
||||
|
||||
private Long modelId;
|
||||
|
||||
private List<Identify> identifiers;
|
||||
|
||||
private List<Dim> dimensions;
|
||||
|
||||
private List<Measure> measures;
|
||||
|
||||
private String filterSql;
|
||||
|
||||
|
||||
|
||||
public List<Dim> getTimeDimension() {
|
||||
if (CollectionUtils.isEmpty(dimensions)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
return dimensions.stream()
|
||||
.filter(dim -> DimensionTypeEnum.time.name().equalsIgnoreCase(dim.getType()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public String getSqlQuery() {
|
||||
if (StringUtils.isNotBlank(sqlQuery) && sqlQuery.endsWith(";")) {
|
||||
sqlQuery = sqlQuery.substring(0, sqlQuery.length() - 1);
|
||||
}
|
||||
return sqlQuery;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,9 +18,6 @@ public class DimensionReq extends SchemaItem {
|
||||
@NotNull(message = "expr can not be null")
|
||||
private String expr;
|
||||
|
||||
|
||||
private Long datasourceId;
|
||||
|
||||
//DATE ID CATEGORY
|
||||
private String semanticType = "CATEGORY";
|
||||
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package com.tencent.supersonic.semantic.api.model.request;
|
||||
|
||||
|
||||
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class DomainReq extends SchemaItem {
|
||||
@@ -24,4 +22,22 @@ public class DomainReq extends SchemaItem {
|
||||
private List<String> admins = new ArrayList<>();
|
||||
|
||||
private List<String> adminOrgs = new ArrayList<>();
|
||||
|
||||
public String getViewer() {
|
||||
return String.join(",", viewers);
|
||||
}
|
||||
|
||||
public String getViewOrg() {
|
||||
return String.join(",", viewOrgs);
|
||||
}
|
||||
|
||||
|
||||
public String getAdmin() {
|
||||
return String.join(",", admins);
|
||||
}
|
||||
|
||||
public String getAdminOrg() {
|
||||
return String.join(",", adminOrgs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,37 @@
|
||||
package com.tencent.supersonic.semantic.api.model.request;
|
||||
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.DimensionTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Dim;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Entity;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ModelDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import lombok.Data;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Data
|
||||
public class ModelReq extends SchemaItem {
|
||||
|
||||
private Long domainId = 0L;
|
||||
private Long databaseId;
|
||||
|
||||
private Integer isOpen = 0;
|
||||
private Long domainId;
|
||||
|
||||
private String filterSql;
|
||||
|
||||
private Integer isOpen;
|
||||
|
||||
private List<DrillDownDimension> drillDownDimensions;
|
||||
|
||||
private String alias;
|
||||
|
||||
private ModelDetail modelDetail;
|
||||
|
||||
private List<String> viewers = new ArrayList<>();
|
||||
|
||||
private List<String> viewOrgs = new ArrayList<>();
|
||||
@@ -27,9 +40,16 @@ public class ModelReq extends SchemaItem {
|
||||
|
||||
private List<String> adminOrgs = new ArrayList<>();
|
||||
|
||||
private Entity entity;
|
||||
|
||||
private List<DrillDownDimension> drillDownDimensions;
|
||||
public List<Dim> getTimeDimension() {
|
||||
if (CollectionUtils.isEmpty(modelDetail.getDimensions())) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
return modelDetail.getDimensions().stream()
|
||||
.filter(dim -> DimensionTypeEnum.time.name().equalsIgnoreCase(dim.getType()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
public String getViewer() {
|
||||
return String.join(",", viewers);
|
||||
@@ -48,4 +68,5 @@ public class ModelReq extends SchemaItem {
|
||||
return String.join(",", adminOrgs);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.api.model.response;
|
||||
|
||||
import java.util.Date;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DatasourceRelaResp {
|
||||
|
||||
private Long id;
|
||||
|
||||
private Long domainId;
|
||||
|
||||
private Long datasourceFrom;
|
||||
|
||||
private Long datasourceTo;
|
||||
|
||||
private String joinKey;
|
||||
|
||||
private Date createdAt;
|
||||
|
||||
private String createdBy;
|
||||
|
||||
private Date updatedAt;
|
||||
|
||||
private String updatedBy;
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.api.model.response;
|
||||
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DatasourceDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DatasourceResp extends SchemaItem {
|
||||
|
||||
private Long modelId;
|
||||
|
||||
private Long databaseId;
|
||||
|
||||
private DatasourceDetail datasourceDetail;
|
||||
|
||||
private String depends;
|
||||
|
||||
private String filterSql;
|
||||
|
||||
}
|
||||
@@ -3,10 +3,14 @@ package com.tencent.supersonic.semantic.api.model.response;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class DimSchemaResp extends DimensionResp {
|
||||
|
||||
private Long useCnt = 0L;
|
||||
|
||||
private List<String> entityAlias;
|
||||
|
||||
}
|
||||
@@ -22,13 +22,11 @@ public class DimensionResp extends SchemaItem {
|
||||
|
||||
private String fullPath;
|
||||
|
||||
private Long datasourceId;
|
||||
private String modelName;
|
||||
|
||||
private String datasourceName;
|
||||
private String modelBizName;
|
||||
|
||||
private String datasourceBizName;
|
||||
|
||||
private String datasourceFilterSql;
|
||||
private String modelFilterSql;
|
||||
//DATE ID CATEGORY
|
||||
private String semanticType;
|
||||
|
||||
|
||||
@@ -46,8 +46,6 @@ public class MetricResp extends SchemaItem {
|
||||
|
||||
private boolean hasAdminRes = false;
|
||||
|
||||
private String defaultAgg;
|
||||
|
||||
public void setTag(String tag) {
|
||||
if (StringUtils.isBlank(tag)) {
|
||||
tags = Lists.newArrayList();
|
||||
@@ -80,4 +78,8 @@ public class MetricResp extends SchemaItem {
|
||||
}
|
||||
return typeParams.getMeasures();
|
||||
}
|
||||
|
||||
public String getDefaultAgg() {
|
||||
return typeParams.getMeasures().get(0).getAgg();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,66 @@
|
||||
package com.tencent.supersonic.semantic.api.model.response;
|
||||
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ModelDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Entity;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public class ModelResp extends SchemaItem {
|
||||
|
||||
private Long domainId;
|
||||
|
||||
private Long databaseId;
|
||||
|
||||
private ModelDetail modelDetail;
|
||||
|
||||
private String depends;
|
||||
|
||||
private String filterSql;
|
||||
|
||||
private List<String> viewers = new ArrayList<>();
|
||||
|
||||
private List<String> viewOrgs = new ArrayList<>();
|
||||
|
||||
private List<String> admins = new ArrayList<>();
|
||||
|
||||
private List<String> adminOrgs = new ArrayList<>();
|
||||
|
||||
private Integer isOpen;
|
||||
|
||||
private List<DrillDownDimension> drillDownDimensions;
|
||||
|
||||
private String alias;
|
||||
|
||||
private List<String> viewers;
|
||||
|
||||
private List<String> viewOrgs;
|
||||
|
||||
private List<String> admins;
|
||||
|
||||
private List<String> adminOrgs;
|
||||
|
||||
private Integer isOpen = 0;
|
||||
private String fullPath;
|
||||
|
||||
private Integer dimensionCnt;
|
||||
|
||||
private Integer metricCnt;
|
||||
|
||||
private Entity entity;
|
||||
|
||||
private String fullPath;
|
||||
|
||||
private List<DrillDownDimension> drillDownDimensions;
|
||||
|
||||
public boolean openToAll() {
|
||||
return isOpen != null && isOpen == 1;
|
||||
}
|
||||
|
||||
public Identify getPrimaryIdentify() {
|
||||
if (modelDetail == null) {
|
||||
return null;
|
||||
}
|
||||
if (CollectionUtils.isEmpty(modelDetail.getIdentifiers())) {
|
||||
return null;
|
||||
}
|
||||
for (Identify identify : modelDetail.getIdentifiers()) {
|
||||
if (!CollectionUtils.isEmpty(identify.getEntityNames())) {
|
||||
return identify;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package com.tencent.supersonic.semantic.api.model.response;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ModelSchemaRelaResp {
|
||||
|
||||
private Long domainId;
|
||||
|
||||
private DatasourceResp datasource;
|
||||
private ModelResp model;
|
||||
|
||||
private List<MetricResp> metrics;
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.tencent.supersonic.semantic.api.model.response;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.tencent.supersonic.common.pojo.ModelRela;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@@ -13,5 +15,20 @@ public class ModelSchemaResp extends ModelResp {
|
||||
|
||||
private List<MetricSchemaResp> metrics;
|
||||
private List<DimSchemaResp> dimensions;
|
||||
private List<ModelRela> modelRelas;
|
||||
|
||||
public DimSchemaResp getPrimaryKey() {
|
||||
Identify identify = getPrimaryIdentify();
|
||||
if (identify == null) {
|
||||
return null;
|
||||
}
|
||||
for (DimSchemaResp dimension : dimensions) {
|
||||
if (identify.getBizName().equals(dimension.getBizName())) {
|
||||
dimension.setEntityAlias(identify.getEntityNames());
|
||||
return dimension;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class DatasourceYamlTpl {
|
||||
public class DataModelYamlTpl {
|
||||
|
||||
private String name;
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
package com.tencent.supersonic.semantic.api.query.request;
|
||||
|
||||
import java.util.Map;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public class QueryS2SQLReq {
|
||||
|
||||
private Long modelId;
|
||||
private Set<Long> modelIds;
|
||||
|
||||
private String sql;
|
||||
|
||||
private Map<String, String> variables;
|
||||
|
||||
public void setModelId(Long modelId) {
|
||||
modelIds = new HashSet<>();
|
||||
modelIds.add(modelId);
|
||||
}
|
||||
|
||||
public List<Long> getModelIds() {
|
||||
return Lists.newArrayList(modelIds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,11 +14,6 @@ import com.tencent.supersonic.common.util.SqlFilterUtils;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserAddHelper;
|
||||
import com.tencent.supersonic.semantic.api.query.pojo.Cache;
|
||||
import com.tencent.supersonic.semantic.api.query.pojo.Param;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
@@ -42,12 +37,20 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Data
|
||||
@Slf4j
|
||||
public class QueryStructReq {
|
||||
|
||||
private Long modelId;
|
||||
private Set<Long> modelIds;
|
||||
|
||||
private String modelName;
|
||||
private List<String> groups = new ArrayList<>();
|
||||
@@ -70,6 +73,19 @@ public class QueryStructReq {
|
||||
*/
|
||||
private String correctS2SQL;
|
||||
|
||||
public void setModelId(Long modelId) {
|
||||
modelIds = new HashSet<>();
|
||||
modelIds.add(modelId);
|
||||
}
|
||||
|
||||
public List<Long> getModelIds() {
|
||||
return Lists.newArrayList(modelIds);
|
||||
}
|
||||
|
||||
public Set<Long> getModelIdSet() {
|
||||
return modelIds;
|
||||
}
|
||||
|
||||
public List<String> getGroups() {
|
||||
if (!CollectionUtils.isEmpty(this.groups)) {
|
||||
this.groups = groups.stream().filter(group -> !Strings.isEmpty(group)).collect(Collectors.toList());
|
||||
@@ -107,7 +123,7 @@ public class QueryStructReq {
|
||||
public String toCustomizedString() {
|
||||
StringBuilder stringBuilder = new StringBuilder("{");
|
||||
stringBuilder.append("\"modelId\":")
|
||||
.append(modelId);
|
||||
.append(modelIds);
|
||||
stringBuilder.append(",\"groups\":")
|
||||
.append(groups);
|
||||
stringBuilder.append(",\"aggregators\":")
|
||||
@@ -139,7 +155,7 @@ public class QueryStructReq {
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("{");
|
||||
sb.append("\"modelId\":")
|
||||
.append(modelId);
|
||||
.append(modelIds);
|
||||
sb.append(",\"groups\":")
|
||||
.append(groups);
|
||||
sb.append(",\"aggregators\":")
|
||||
@@ -179,7 +195,7 @@ public class QueryStructReq {
|
||||
|
||||
QueryS2SQLReq result = new QueryS2SQLReq();
|
||||
result.setSql(sql);
|
||||
result.setModelId(queryStructReq.getModelId());
|
||||
result.setModelIds(queryStructReq.getModelIdSet());
|
||||
result.setVariables(new HashMap<>());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@ import com.tencent.supersonic.semantic.api.materialization.response.Materializat
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
import com.tencent.supersonic.semantic.materialization.domain.MaterializationConfService;
|
||||
import com.tencent.supersonic.semantic.materialization.domain.pojo.Materialization;
|
||||
@@ -32,8 +32,11 @@ import com.tencent.supersonic.semantic.materialization.domain.repository.Materia
|
||||
import com.tencent.supersonic.semantic.materialization.domain.repository.MaterializationRepository;
|
||||
import com.tencent.supersonic.semantic.materialization.domain.utils.MaterializationConverter;
|
||||
import com.tencent.supersonic.semantic.materialization.domain.utils.MaterializationZipperUtils;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -46,11 +49,6 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@@ -59,18 +57,16 @@ public class MaterializationConfServiceImpl implements MaterializationConfServic
|
||||
private final MaterializationRepository materializationRepository;
|
||||
private final MaterializationElementRepository materializationElementRepository;
|
||||
private final ModelService modelService;
|
||||
private final DatasourceService datasourceService;
|
||||
private final MaterializationZipperUtils materializationZipperUtils;
|
||||
private String typeAndIdSplit = "_";
|
||||
|
||||
public MaterializationConfServiceImpl(MaterializationRepository materializationRepository,
|
||||
MaterializationElementRepository materializationElementRepository,
|
||||
ModelService modelService, DatasourceService datasourceService,
|
||||
ModelService modelService,
|
||||
MaterializationZipperUtils materializationZipperUtils) {
|
||||
this.materializationRepository = materializationRepository;
|
||||
this.materializationElementRepository = materializationElementRepository;
|
||||
this.modelService = modelService;
|
||||
this.datasourceService = datasourceService;
|
||||
this.materializationZipperUtils = materializationZipperUtils;
|
||||
}
|
||||
|
||||
@@ -309,7 +305,7 @@ public class MaterializationConfServiceImpl implements MaterializationConfServic
|
||||
ModelSchemaFilterReq modelFilter = new ModelSchemaFilterReq();
|
||||
modelFilter.setModelIds(Arrays.asList(materializationResp.getModelId()));
|
||||
List<ModelSchemaResp> modelSchemaRespList = modelService.fetchModelSchema(modelFilter);
|
||||
List<MeasureResp> measureRespList = datasourceService.getMeasureListOfModel(
|
||||
List<MeasureResp> measureRespList = modelService.getMeasureListOfModel(
|
||||
Lists.newArrayList(materializationResp.getModelId()));
|
||||
Map<String, DimSchemaResp> dimSchemaRespMap = new HashMap<>();
|
||||
Map<String, MetricSchemaResp> metricSchemaRespHashMap = new HashMap<>();
|
||||
@@ -363,13 +359,11 @@ public class MaterializationConfServiceImpl implements MaterializationConfServic
|
||||
@Override
|
||||
public List<MaterializationSourceResp> getMaterializationSourceResp(
|
||||
Long materializationId) {
|
||||
|
||||
MaterializationResp materializationResp = materializationRepository.getMaterialization(
|
||||
materializationId);
|
||||
Long modelId = materializationResp.getModelId();
|
||||
List<DatasourceResp> modelDataSources = datasourceService.getDatasourceList(modelId);
|
||||
|
||||
Set<Long> dataSourceIds = new HashSet<>();
|
||||
Set<Long> modelIds = new HashSet<>();
|
||||
Map<Long, Map<Long, String>> dataSourceDimensions = new HashMap<>();
|
||||
Map<Long, Map<Long, String>> dataSourceMetrics = new HashMap<>();
|
||||
MaterializationConfFilter materializationConfFilter = new MaterializationConfFilter();
|
||||
@@ -380,7 +374,7 @@ public class MaterializationConfServiceImpl implements MaterializationConfServic
|
||||
ModelSchemaFilterReq modelSchemaFilterReq = new ModelSchemaFilterReq();
|
||||
modelSchemaFilterReq.setModelIds(Arrays.asList(modelId));
|
||||
List<ModelSchemaResp> modelSchemaRespList = modelService.fetchModelSchema(modelSchemaFilterReq);
|
||||
List<MeasureResp> measureRespList = datasourceService.getMeasureListOfModel(Lists.newArrayList(modelId));
|
||||
List<MeasureResp> measureRespList = modelService.getMeasureListOfModel(Lists.newArrayList(modelId));
|
||||
Set<Long> dimensionIds = new HashSet<>();
|
||||
Set<Long> metricIds = new HashSet<>();
|
||||
materializationElementRespList.stream().forEach(e -> {
|
||||
@@ -393,11 +387,11 @@ public class MaterializationConfServiceImpl implements MaterializationConfServic
|
||||
});
|
||||
modelSchemaRespList.stream().forEach(m -> {
|
||||
m.getDimensions().stream().filter(mm -> dimensionIds.contains(mm.getId())).forEach(mm -> {
|
||||
if (!dataSourceDimensions.containsKey(mm.getDatasourceId())) {
|
||||
dataSourceDimensions.put(mm.getDatasourceId(), new HashMap<>());
|
||||
if (!dataSourceDimensions.containsKey(mm.getModelId())) {
|
||||
dataSourceDimensions.put(mm.getModelId(), new HashMap<>());
|
||||
}
|
||||
dataSourceDimensions.get(mm.getDatasourceId()).put(mm.getId(), mm.getBizName());
|
||||
dataSourceIds.add(mm.getDatasourceId());
|
||||
dataSourceDimensions.get(mm.getModelId()).put(mm.getId(), mm.getBizName());
|
||||
modelIds.add(mm.getModelId());
|
||||
});
|
||||
m.getMetrics().stream().filter(mm -> metricIds.contains(mm.getId())).forEach(mm -> {
|
||||
Long sourceId = 0L;
|
||||
@@ -412,27 +406,29 @@ public class MaterializationConfServiceImpl implements MaterializationConfServic
|
||||
dataSourceMetrics.put(sourceId, new HashMap<>());
|
||||
}
|
||||
dataSourceMetrics.get(sourceId).put(mm.getId(), mm.getBizName());
|
||||
dataSourceIds.add(sourceId);
|
||||
modelIds.add(sourceId);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
List<MaterializationSourceResp> materializationSourceResps = new ArrayList<>();
|
||||
for (Long sourceId : dataSourceIds) {
|
||||
Optional<DatasourceResp> datasourceResp = modelDataSources.stream().filter(d -> d.getId().equals(sourceId))
|
||||
.findFirst();
|
||||
if (datasourceResp.isPresent()) {
|
||||
for (Long sourceId : modelIds) {
|
||||
//todo
|
||||
// Optional<ModelResp> modelResp = modelSchemaRespList.stream().filter(d -> d.getId().equals(sourceId))
|
||||
// .findFirst();
|
||||
Optional<ModelResp> modelResp = Optional.empty();
|
||||
if (modelResp.isPresent()) {
|
||||
MaterializationSourceResp materializationSourceResp = MaterializationSourceResp.builder()
|
||||
.dataSourceId(sourceId)
|
||||
.materializationId(materializationId)
|
||||
.modelId(modelId)
|
||||
.depends(datasourceResp.get().getDepends())
|
||||
.depends(modelResp.get().getDepends())
|
||||
.materializedType(materializationResp.getMaterializedType())
|
||||
.entities(materializationResp.getEntities())
|
||||
.dateInfo(materializationResp.getDateInfo())
|
||||
.updateCycle(materializationResp.getUpdateCycle())
|
||||
.build();
|
||||
setDataSourceDb(datasourceResp.get(), materializationSourceResp);
|
||||
setDataSourceDb(modelResp.get(), materializationSourceResp);
|
||||
materializationSourceResp.setMetrics(
|
||||
dataSourceMetrics.containsKey(sourceId) ? dataSourceMetrics.get(sourceId)
|
||||
: new HashMap<>());
|
||||
@@ -456,16 +452,16 @@ public class MaterializationConfServiceImpl implements MaterializationConfServic
|
||||
return 0L;
|
||||
}
|
||||
|
||||
private void setDataSourceDb(DatasourceResp datasourceResp, MaterializationSourceResp materializationSourceResp) {
|
||||
if (Objects.nonNull(datasourceResp.getDatasourceDetail())) {
|
||||
private void setDataSourceDb(ModelResp datasourceResp, MaterializationSourceResp materializationSourceResp) {
|
||||
if (Objects.nonNull(datasourceResp.getModelDetail())) {
|
||||
String dbTable = "";
|
||||
if (Objects.nonNull(datasourceResp.getDatasourceDetail().getTableQuery())
|
||||
&& !datasourceResp.getDatasourceDetail().getTableQuery().isEmpty()) {
|
||||
dbTable = datasourceResp.getDatasourceDetail().getTableQuery();
|
||||
if (Objects.nonNull(datasourceResp.getModelDetail().getTableQuery())
|
||||
&& !datasourceResp.getModelDetail().getTableQuery().isEmpty()) {
|
||||
dbTable = datasourceResp.getModelDetail().getTableQuery();
|
||||
}
|
||||
if (Objects.nonNull(datasourceResp.getDatasourceDetail().getSqlQuery())
|
||||
&& !datasourceResp.getDatasourceDetail().getSqlQuery().isEmpty()) {
|
||||
dbTable = SqlParserSelectHelper.getDbTableName(datasourceResp.getDatasourceDetail().getSqlQuery());
|
||||
if (Objects.nonNull(datasourceResp.getModelDetail().getSqlQuery())
|
||||
&& !datasourceResp.getModelDetail().getSqlQuery().isEmpty()) {
|
||||
dbTable = SqlParserSelectHelper.getDbTableName(datasourceResp.getModelDetail().getSqlQuery());
|
||||
}
|
||||
if (!dbTable.isEmpty()) {
|
||||
String[] db = dbTable.split("\\.");
|
||||
|
||||
@@ -1,35 +1,30 @@
|
||||
package com.tencent.supersonic.semantic.model.application;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import com.tencent.supersonic.common.pojo.ModelRela;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ItemDateFilter;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DatasourceYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DataModelYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.MetricYamlTpl;
|
||||
import com.tencent.supersonic.semantic.model.domain.Catalog;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatabaseService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelRelaService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -38,18 +33,20 @@ public class CatalogImpl implements Catalog {
|
||||
private final DatabaseService databaseService;
|
||||
private final ModelService modelService;
|
||||
private final DimensionService dimensionService;
|
||||
private final DatasourceService datasourceService;
|
||||
private final ModelService datasourceService;
|
||||
private final MetricService metricService;
|
||||
private final ModelRelaService modelRelaService;
|
||||
|
||||
public CatalogImpl(DatabaseService databaseService,
|
||||
ModelService modelService, DimensionService dimensionService,
|
||||
DatasourceService datasourceService,
|
||||
MetricService metricService) {
|
||||
ModelService datasourceService,
|
||||
MetricService metricService, ModelRelaService modelRelaService) {
|
||||
this.databaseService = databaseService;
|
||||
this.modelService = modelService;
|
||||
this.dimensionService = dimensionService;
|
||||
this.datasourceService = datasourceService;
|
||||
this.metricService = metricService;
|
||||
this.modelRelaService = modelRelaService;
|
||||
}
|
||||
|
||||
public DatabaseResp getDatabase(Long id) {
|
||||
@@ -62,7 +59,7 @@ public class CatalogImpl implements Catalog {
|
||||
|
||||
@Override
|
||||
public String getModelFullPath(Long modelId) {
|
||||
ModelResp modelResp = modelService.getModelMap().get(modelId);
|
||||
ModelResp modelResp = modelService.getModel(modelId);
|
||||
if (modelResp != null) {
|
||||
return modelResp.getFullPath();
|
||||
}
|
||||
@@ -70,8 +67,8 @@ public class CatalogImpl implements Catalog {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, String> getModelFullPath() {
|
||||
return modelService.getModelFullPathMap();
|
||||
public String getModelFullPath(List<Long> modelIds) {
|
||||
return String.join(",", modelIds.stream().map(Object::toString).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,27 +77,21 @@ public class CatalogImpl implements Catalog {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getModelYamlTplByModelIds(Set<Long> modelIds, Map<String, List<DimensionYamlTpl>> dimensionYamlMap,
|
||||
List<DatasourceYamlTpl> datasourceYamlTplList, List<MetricYamlTpl> metricYamlTplList) {
|
||||
datasourceService.getModelYamlTplByModelIds(modelIds, dimensionYamlMap, datasourceYamlTplList,
|
||||
metricYamlTplList);
|
||||
public List<ModelRela> getModelRela(List<Long> modelIds) {
|
||||
return modelRelaService.getModelRela(modelIds);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<DimensionResp> getDimensions(Long modelId) {
|
||||
MetaFilter metricFilter = new MetaFilter(Lists.newArrayList(modelId));
|
||||
public List<DimensionResp> getDimensions(List<Long> modelIds) {
|
||||
MetaFilter metricFilter = new MetaFilter(modelIds);
|
||||
metricFilter.setStatus(StatusEnum.ONLINE.getCode());
|
||||
return dimensionService.getDimensions(metricFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasourceResp> getDatasourceList(Long modelId) {
|
||||
return datasourceService.getDatasourceList(modelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetricResp> getMetrics(Long modelId) {
|
||||
MetaFilter metricFilter = new MetaFilter(Lists.newArrayList(modelId));
|
||||
public List<MetricResp> getMetrics(List<Long> modelIds) {
|
||||
MetaFilter metricFilter = new MetaFilter(modelIds);
|
||||
return metricService.getMetrics(metricFilter);
|
||||
}
|
||||
|
||||
@@ -110,33 +101,11 @@ public class CatalogImpl implements Catalog {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAgg(List<MetricResp> metricResps, List<MeasureResp> measureRespList, String metricBizName) {
|
||||
try {
|
||||
if (!CollectionUtils.isEmpty(metricResps)) {
|
||||
Optional<MetricResp> metric = metricResps.stream()
|
||||
.filter(m -> m.getBizName().equalsIgnoreCase(metricBizName)).findFirst();
|
||||
if (metric.isPresent() && Objects.nonNull(metric.get().getTypeParams()) && !CollectionUtils.isEmpty(
|
||||
metric.get().getTypeParams().getMeasures())) {
|
||||
if (!CollectionUtils.isEmpty(measureRespList)) {
|
||||
String measureName = metric.get().getTypeParams().getMeasures().get(0).getBizName();
|
||||
Optional<MeasureResp> measure = measureRespList.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(m -> {
|
||||
if (StringUtils.isNotEmpty(m.getBizName())) {
|
||||
return m.getBizName().equalsIgnoreCase(measureName);
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.findFirst();
|
||||
if (measure.isPresent()) {
|
||||
return measure.get().getAgg();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("getAgg:", e);
|
||||
}
|
||||
return "";
|
||||
public void getModelYamlTplByModelIds(Set<Long> modelIds, Map<String, List<DimensionYamlTpl>> dimensionYamlMap,
|
||||
List<DataModelYamlTpl> dataModelYamlTplList, List<MetricYamlTpl> metricYamlTplList,
|
||||
Map<Long, String> modelIdName) {
|
||||
datasourceService.getModelYamlTplByModelIds(modelIds, dimensionYamlMap, dataModelYamlTplList,
|
||||
metricYamlTplList, modelIdName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,25 +3,27 @@ package com.tencent.supersonic.semantic.model.application;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DatabaseReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatabaseService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.adaptor.engineadapter.EngineAdaptor;
|
||||
import com.tencent.supersonic.semantic.model.domain.adaptor.engineadapter.EngineAdaptorFactory;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DatabaseDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.Database;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.ModelFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DatabaseRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.DatabaseConverter;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.JdbcDataSourceUtils;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.SqlUtils;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatabaseService;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.Database;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@@ -29,11 +31,11 @@ public class DatabaseServiceImpl implements DatabaseService {
|
||||
|
||||
private final SqlUtils sqlUtils;
|
||||
private DatabaseRepository databaseRepository;
|
||||
private DatasourceService datasourceService;
|
||||
private ModelService datasourceService;
|
||||
|
||||
public DatabaseServiceImpl(DatabaseRepository databaseRepository,
|
||||
SqlUtils sqlUtils,
|
||||
@Lazy DatasourceService datasourceService) {
|
||||
@Lazy ModelService datasourceService) {
|
||||
this.databaseRepository = databaseRepository;
|
||||
this.sqlUtils = sqlUtils;
|
||||
this.datasourceService = datasourceService;
|
||||
@@ -88,11 +90,13 @@ public class DatabaseServiceImpl implements DatabaseService {
|
||||
|
||||
@Override
|
||||
public void deleteDatabase(Long databaseId) {
|
||||
List<DatasourceResp> datasourceResps = datasourceService.getDatasourceByDatabase(databaseId);
|
||||
if (!CollectionUtils.isEmpty(datasourceResps)) {
|
||||
List<String> datasourceNames = datasourceResps.stream()
|
||||
.map(DatasourceResp::getName).collect(Collectors.toList());
|
||||
String message = String.format("该数据库被数据源%s使用,无法删除", datasourceNames);
|
||||
ModelFilter modelFilter = new ModelFilter();
|
||||
modelFilter.setDatabaseId(databaseId);
|
||||
List<ModelResp> modelResps = datasourceService.getModelList(modelFilter);
|
||||
if (!CollectionUtils.isEmpty(modelResps)) {
|
||||
List<String> datasourceNames = modelResps.stream()
|
||||
.map(ModelResp::getName).collect(Collectors.toList());
|
||||
String message = String.format("该数据库被模型%s使用,无法删除", datasourceNames);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
databaseRepository.deleteDatabase(databaseId);
|
||||
|
||||
@@ -1,355 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.model.application;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.pojo.exception.InvalidArgumentException;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DatasourceDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Dim;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ItemDateFilter;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DatasourceYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.MetricYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DatasourceReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DateInfoReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DimensionReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatabaseService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DatasourceDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DateInfoDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.manager.DatasourceYamlManager;
|
||||
import com.tencent.supersonic.semantic.model.domain.manager.DimensionYamlManager;
|
||||
import com.tencent.supersonic.semantic.model.domain.manager.MetricYamlManager;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DatasourceRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DateInfoRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.DatasourceConverter;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.DimensionConverter;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.MetricConverter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.NameCheckUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class DatasourceServiceImpl implements DatasourceService {
|
||||
|
||||
private DatasourceRepository datasourceRepository;
|
||||
|
||||
private DatabaseService databaseService;
|
||||
|
||||
private DimensionService dimensionService;
|
||||
|
||||
private MetricService metricService;
|
||||
|
||||
private DateInfoRepository dateInfoRepository;
|
||||
|
||||
public DatasourceServiceImpl(DatasourceRepository datasourceRepository,
|
||||
DatabaseService databaseService,
|
||||
@Lazy DimensionService dimensionService,
|
||||
@Lazy MetricService metricService,
|
||||
DateInfoRepository dateInfoRepository) {
|
||||
this.datasourceRepository = datasourceRepository;
|
||||
this.databaseService = databaseService;
|
||||
this.dimensionService = dimensionService;
|
||||
this.metricService = metricService;
|
||||
this.dateInfoRepository = dateInfoRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public DatasourceResp createDatasource(DatasourceReq datasourceReq, User user) throws Exception {
|
||||
checkName(datasourceReq);
|
||||
checkExist(datasourceReq);
|
||||
DatasourceDO datasourceDO = DatasourceConverter.convert(datasourceReq, user);
|
||||
datasourceRepository.createDatasource(datasourceDO);
|
||||
batchCreateDimension(datasourceDO, user);
|
||||
batchCreateMetric(datasourceDO, user);
|
||||
return DatasourceConverter.convert(datasourceDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public DatasourceResp updateDatasource(DatasourceReq datasourceReq, User user) throws Exception {
|
||||
checkName(datasourceReq);
|
||||
DatasourceDO datasourceDO = datasourceRepository.getDatasourceById(datasourceReq.getId());
|
||||
DatasourceConverter.convert(datasourceDO, datasourceReq, user);
|
||||
datasourceRepository.updateDatasource(datasourceDO);
|
||||
batchCreateDimension(datasourceDO, user);
|
||||
batchCreateMetric(datasourceDO, user);
|
||||
return DatasourceConverter.convert(datasourceDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MeasureResp> getMeasureListOfModel(List<Long> modelIds) {
|
||||
if (CollectionUtils.isEmpty(modelIds)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
List<DatasourceResp> datasourceResps = getDatasourceList().stream().filter(datasourceResp ->
|
||||
modelIds.contains(datasourceResp.getModelId())).collect(Collectors.toList());
|
||||
List<MeasureResp> measureResps = Lists.newArrayList();
|
||||
if (!CollectionUtils.isEmpty(datasourceResps)) {
|
||||
for (DatasourceResp datasourceDesc : datasourceResps) {
|
||||
DatasourceDetail datasourceDetail = datasourceDesc.getDatasourceDetail();
|
||||
List<Measure> measures = datasourceDetail.getMeasures();
|
||||
if (!CollectionUtils.isEmpty(measures)) {
|
||||
measureResps.addAll(
|
||||
measures.stream().map(measure -> DatasourceConverter.convert(measure, datasourceDesc))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return measureResps;
|
||||
}
|
||||
|
||||
private void batchCreateDimension(DatasourceDO datasourceDO, User user) throws Exception {
|
||||
List<DimensionReq> dimensionReqs = DatasourceConverter.convertDimensionList(datasourceDO);
|
||||
dimensionService.createDimensionBatch(dimensionReqs, user);
|
||||
}
|
||||
|
||||
private void batchCreateMetric(DatasourceDO datasourceDO, User user) throws Exception {
|
||||
List<MetricReq> exprMetricReqs = DatasourceConverter.convertMetricList(datasourceDO);
|
||||
metricService.createMetricBatch(exprMetricReqs, user);
|
||||
}
|
||||
|
||||
private Optional<DatasourceResp> getDatasource(Long modelId, String bizName) {
|
||||
List<DatasourceResp> datasourceResps = getDatasourceList(modelId);
|
||||
if (CollectionUtils.isEmpty(datasourceResps)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
for (DatasourceResp datasourceDesc : datasourceResps) {
|
||||
if (datasourceDesc.getBizName().equals(bizName)) {
|
||||
return Optional.of(datasourceDesc);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void checkName(DatasourceReq datasourceReq) {
|
||||
if (NameCheckUtils.containsSpecialCharacters(datasourceReq.getName())) {
|
||||
String message = String.format("数据源名称[%s]包含特殊字符, 请修改", datasourceReq.getName());
|
||||
throw new InvalidArgumentException(message);
|
||||
}
|
||||
List<Dim> dims = datasourceReq.getDimensions();
|
||||
List<Measure> measures = datasourceReq.getMeasures();
|
||||
List<Dim> timeDims = datasourceReq.getTimeDimension();
|
||||
List<Identify> identifies = datasourceReq.getIdentifiers();
|
||||
if (CollectionUtils.isEmpty(dims)) {
|
||||
throw new InvalidArgumentException("缺少维度信息");
|
||||
}
|
||||
if (CollectionUtils.isEmpty(identifies)) {
|
||||
throw new InvalidArgumentException("缺少主键信息");
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(measures) && CollectionUtils.isEmpty(timeDims)) {
|
||||
throw new InvalidArgumentException("有度量时, 不可缺少时间维度");
|
||||
}
|
||||
for (Measure measure : measures) {
|
||||
if (StringUtils.isNotBlank(measure.getName())
|
||||
&& NameCheckUtils.containsSpecialCharacters(measure.getName())) {
|
||||
String message = String.format("度量[%s]包含特殊字符, 请修改", measure.getName());
|
||||
throw new InvalidArgumentException(message);
|
||||
}
|
||||
}
|
||||
for (Dim dim : dims) {
|
||||
if (StringUtils.isNotBlank(dim.getName())
|
||||
&& NameCheckUtils.containsSpecialCharacters(dim.getName())) {
|
||||
String message = String.format("维度[%s]包含特殊字符, 请修改", dim.getName());
|
||||
throw new InvalidArgumentException(message);
|
||||
}
|
||||
}
|
||||
for (Identify identify : identifies) {
|
||||
if (StringUtils.isNotBlank(identify.getName())
|
||||
&& NameCheckUtils.containsSpecialCharacters(identify.getName())) {
|
||||
String message = String.format("主键/外键[%s]包含特殊字符, 请修改", identify.getName());
|
||||
throw new InvalidArgumentException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkExist(DatasourceReq datasourceReq) {
|
||||
Optional<DatasourceResp> datasourceRespOptional = getDatasource(datasourceReq.getModelId(),
|
||||
datasourceReq.getBizName());
|
||||
if (datasourceRespOptional.isPresent()) {
|
||||
throw new InvalidArgumentException("已存在相同名字的数据源:" + datasourceReq.getBizName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasourceResp> getDatasourceList(Long modelId) {
|
||||
return DatasourceConverter.convertList(datasourceRepository.getDatasourceList(modelId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasourceResp> getDatasourceList() {
|
||||
return DatasourceConverter.convertList(datasourceRepository.getDatasourceList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasourceResp> getDatasourceByDatabase(Long databaseId) {
|
||||
return DatasourceConverter.convertList(datasourceRepository.getDatasourceByDatabase(databaseId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasourceResp> getDatasourceListNoMeasurePrefix(Long modelId) {
|
||||
List<DatasourceResp> datasourceResps = getDatasourceList(modelId);
|
||||
for (DatasourceResp datasourceResp : datasourceResps) {
|
||||
if (!CollectionUtils.isEmpty(datasourceResp.getDatasourceDetail().getMeasures())) {
|
||||
for (Measure measure : datasourceResp.getDatasourceDetail().getMeasures()) {
|
||||
measure.setBizName(Optional.ofNullable(measure.getBizName()).orElse("")
|
||||
.replace(getDatasourcePrefix(datasourceResp.getBizName()), ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
return datasourceResps;
|
||||
}
|
||||
|
||||
private String getDatasourcePrefix(String datasourceBizName) {
|
||||
return String.format("%s_", datasourceBizName);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<Long, DatasourceResp> getDatasourceMap() {
|
||||
Map<Long, DatasourceResp> map = new HashMap<>();
|
||||
List<DatasourceResp> datasourceResps = getDatasourceList();
|
||||
if (CollectionUtils.isEmpty(datasourceResps)) {
|
||||
return map;
|
||||
}
|
||||
return datasourceResps.stream().collect(Collectors.toMap(DatasourceResp::getId, a -> a, (k1, k2) -> k1));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void deleteDatasource(Long id, User user) {
|
||||
DatasourceDO datasourceDO = datasourceRepository.getDatasourceById(id);
|
||||
if (datasourceDO == null) {
|
||||
return;
|
||||
}
|
||||
checkDelete(id);
|
||||
datasourceDO.setStatus(StatusEnum.DELETED.getCode());
|
||||
datasourceDO.setUpdatedAt(new Date());
|
||||
datasourceDO.setUpdatedBy(user.getName());
|
||||
datasourceRepository.updateDatasource(datasourceDO);
|
||||
}
|
||||
|
||||
private void checkDelete(Long datasourceId) {
|
||||
MetaFilter metaFilter = new MetaFilter();
|
||||
metaFilter.setDatasourceId(datasourceId);
|
||||
List<MetricResp> metricResps = metricService.getMetrics(metaFilter);
|
||||
List<DimensionResp> dimensionResps = dimensionService.getDimensions(metaFilter);
|
||||
if (!CollectionUtils.isEmpty(metricResps) || !CollectionUtils.isEmpty(dimensionResps)) {
|
||||
throw new RuntimeException("存在基于该数据源创建的指标和维度, 暂不能删除, 请确认");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemDateResp getItemDate(ItemDateFilter dimension, ItemDateFilter metric) {
|
||||
List<DateInfoReq> itemDates = new ArrayList<>();
|
||||
List<DateInfoDO> dimensions = dateInfoRepository.getDateInfos(dimension);
|
||||
List<DateInfoDO> metrics = dateInfoRepository.getDateInfos(metric);
|
||||
|
||||
log.info("getDateDate, dimension:{}, dimensions dateInfo:{}", dimension, dimensions);
|
||||
log.info("getDateDate, metric:{}, metrics dateInfo:{}", metric, metrics);
|
||||
itemDates.addAll(convert(dimensions));
|
||||
itemDates.addAll(convert(metrics));
|
||||
|
||||
ItemDateResp itemDateDescriptor = calculateDateInternal(itemDates);
|
||||
log.info("itemDateDescriptor:{}", itemDateDescriptor);
|
||||
|
||||
return itemDateDescriptor;
|
||||
}
|
||||
|
||||
private List<DateInfoReq> convert(List<DateInfoDO> dateInfoDOList) {
|
||||
List<DateInfoReq> dateInfoCommendList = new ArrayList<>();
|
||||
dateInfoDOList.stream().forEach(dateInfoDO -> {
|
||||
DateInfoReq dateInfoCommend = new DateInfoReq();
|
||||
BeanUtils.copyProperties(dateInfoDO, dateInfoCommend);
|
||||
dateInfoCommend.setUnavailableDateList(JsonUtil.toList(dateInfoDO.getUnavailableDateList(), String.class));
|
||||
dateInfoCommendList.add(dateInfoCommend);
|
||||
});
|
||||
return dateInfoCommendList;
|
||||
}
|
||||
|
||||
private ItemDateResp calculateDateInternal(List<DateInfoReq> itemDates) {
|
||||
if (CollectionUtils.isEmpty(itemDates)) {
|
||||
log.warn("itemDates is empty!");
|
||||
return null;
|
||||
}
|
||||
String dateFormat = itemDates.get(0).getDateFormat();
|
||||
String startDate = itemDates.get(0).getStartDate();
|
||||
String endDate = itemDates.get(0).getEndDate();
|
||||
String datePeriod = itemDates.get(0).getDatePeriod();
|
||||
List<String> unavailableDateList = itemDates.get(0).getUnavailableDateList();
|
||||
for (DateInfoReq item : itemDates) {
|
||||
String startDate1 = item.getStartDate();
|
||||
String endDate1 = item.getEndDate();
|
||||
List<String> unavailableDateList1 = item.getUnavailableDateList();
|
||||
if (Strings.isNotEmpty(startDate1) && startDate1.compareTo(startDate) > 0) {
|
||||
startDate = startDate1;
|
||||
}
|
||||
if (Strings.isNotEmpty(endDate1) && endDate1.compareTo(endDate) < 0) {
|
||||
endDate = endDate1;
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(unavailableDateList1)) {
|
||||
unavailableDateList.addAll(unavailableDateList1);
|
||||
}
|
||||
}
|
||||
|
||||
return new ItemDateResp(dateFormat, startDate, endDate, datePeriod, unavailableDateList);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getModelYamlTplByModelIds(Set<Long> modelIds, Map<String, List<DimensionYamlTpl>> dimensionYamlMap,
|
||||
List<DatasourceYamlTpl> datasourceYamlTplList, List<MetricYamlTpl> metricYamlTplList) {
|
||||
for (Long modelId : modelIds) {
|
||||
List<DatasourceResp> datasourceResps = getDatasourceList(modelId);
|
||||
MetaFilter metaFilter = new MetaFilter(Lists.newArrayList(modelId));
|
||||
List<MetricResp> metricResps = metricService.getMetrics(metaFilter);
|
||||
metricYamlTplList.addAll(MetricYamlManager.convert2YamlObj(MetricConverter.metricInfo2Metric(metricResps)));
|
||||
Long databaseId = datasourceResps.iterator().next().getDatabaseId();
|
||||
DatabaseResp databaseResp = databaseService.getDatabase(databaseId);
|
||||
List<DimensionResp> dimensionResps = dimensionService.getDimensions(metaFilter);
|
||||
for (DatasourceResp datasourceResp : datasourceResps) {
|
||||
datasourceYamlTplList.add(DatasourceYamlManager.convert2YamlObj(
|
||||
DatasourceConverter.datasourceInfo2Datasource(datasourceResp), databaseResp));
|
||||
if (!dimensionYamlMap.containsKey(datasourceResp.getBizName())) {
|
||||
dimensionYamlMap.put(datasourceResp.getBizName(), new ArrayList<>());
|
||||
}
|
||||
List<DimensionResp> dimensionRespList = dimensionResps.stream()
|
||||
.filter(d -> d.getDatasourceBizName().equalsIgnoreCase(datasourceResp.getBizName()))
|
||||
.collect(Collectors.toList());
|
||||
dimensionYamlMap.get(datasourceResp.getBizName()).addAll(DimensionYamlManager.convert2DimensionYaml(
|
||||
DimensionConverter.dimensionInfo2Dimension(dimensionRespList)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,37 +7,30 @@ import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.DataItem;
|
||||
import com.tencent.supersonic.common.pojo.DataEvent;
|
||||
import com.tencent.supersonic.common.pojo.DataItem;
|
||||
import com.tencent.supersonic.common.pojo.enums.EventType;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
|
||||
import com.tencent.supersonic.common.pojo.exception.InvalidArgumentException;
|
||||
import com.tencent.supersonic.common.util.ChatGptHelper;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DatasourceDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DimValueMap;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ModelDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DimensionReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetaBatchReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.PageDimensionReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatabaseService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DimensionDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.DimensionFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DimensionRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.DimensionConverter;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.DimensionFilter;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.NameCheckUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@@ -46,6 +39,13 @@ import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -54,8 +54,6 @@ public class DimensionServiceImpl implements DimensionService {
|
||||
|
||||
private DimensionRepository dimensionRepository;
|
||||
|
||||
private DatasourceService datasourceService;
|
||||
|
||||
private ModelService modelService;
|
||||
|
||||
private ChatGptHelper chatGptHelper;
|
||||
@@ -68,12 +66,10 @@ public class DimensionServiceImpl implements DimensionService {
|
||||
|
||||
public DimensionServiceImpl(DimensionRepository dimensionRepository,
|
||||
ModelService modelService,
|
||||
DatasourceService datasourceService,
|
||||
ChatGptHelper chatGptHelper,
|
||||
DatabaseService databaseService) {
|
||||
this.modelService = modelService;
|
||||
this.dimensionRepository = dimensionRepository;
|
||||
this.datasourceService = datasourceService;
|
||||
this.chatGptHelper = chatGptHelper;
|
||||
this.databaseService = databaseService;
|
||||
}
|
||||
@@ -185,7 +181,7 @@ public class DimensionServiceImpl implements DimensionService {
|
||||
@Override
|
||||
public DimensionResp getDimension(Long id) {
|
||||
DimensionDO dimensionDO = dimensionRepository.getDimensionById(id);
|
||||
return DimensionConverter.convert2DimensionResp(dimensionDO, new HashMap<>(), new HashMap<>());
|
||||
return DimensionConverter.convert2DimensionResp(dimensionDO, new HashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -198,7 +194,7 @@ public class DimensionServiceImpl implements DimensionService {
|
||||
.doSelectPageInfo(() -> queryDimension(dimensionFilter));
|
||||
PageInfo<DimensionResp> pageInfo = new PageInfo<>();
|
||||
BeanUtils.copyProperties(dimensionDOPageInfo, pageInfo);
|
||||
pageInfo.setList(convertList(dimensionDOPageInfo.getList(), datasourceService.getDatasourceMap()));
|
||||
pageInfo.setList(convertList(dimensionDOPageInfo.getList(), modelService.getModelMap()));
|
||||
return pageInfo;
|
||||
}
|
||||
|
||||
@@ -210,7 +206,7 @@ public class DimensionServiceImpl implements DimensionService {
|
||||
public List<DimensionResp> getDimensions(MetaFilter metaFilter) {
|
||||
DimensionFilter dimensionFilter = new DimensionFilter();
|
||||
BeanUtils.copyProperties(metaFilter, dimensionFilter);
|
||||
return convertList(dimensionRepository.getDimension(dimensionFilter), datasourceService.getDatasourceMap());
|
||||
return convertList(dimensionRepository.getDimension(dimensionFilter), modelService.getModelMap());
|
||||
}
|
||||
|
||||
private List<DimensionResp> getDimensions(Long modelId) {
|
||||
@@ -218,13 +214,11 @@ public class DimensionServiceImpl implements DimensionService {
|
||||
}
|
||||
|
||||
private List<DimensionResp> convertList(List<DimensionDO> dimensionDOS,
|
||||
Map<Long, DatasourceResp> datasourceRespMap) {
|
||||
Map<Long, ModelResp> modelRespMap) {
|
||||
List<DimensionResp> dimensionResps = Lists.newArrayList();
|
||||
Map<Long, String> modelFullPathMap = modelService.getModelFullPathMap();
|
||||
if (!CollectionUtils.isEmpty(dimensionDOS)) {
|
||||
dimensionResps = dimensionDOS.stream()
|
||||
.map(dimensionDO -> DimensionConverter.convert2DimensionResp(dimensionDO, modelFullPathMap,
|
||||
datasourceRespMap))
|
||||
.map(dimensionDO -> DimensionConverter.convert2DimensionResp(dimensionDO, modelRespMap))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return dimensionResps;
|
||||
@@ -251,19 +245,10 @@ public class DimensionServiceImpl implements DimensionService {
|
||||
|
||||
@Override
|
||||
public List<DimValueMap> mockDimensionValueAlias(DimensionReq dimensionReq, User user) {
|
||||
|
||||
List<DatasourceResp> datasourceList = datasourceService.getDatasourceList();
|
||||
List<DatasourceResp> collect = datasourceList.stream().filter(datasourceResp ->
|
||||
datasourceResp.getId().equals(dimensionReq.getDatasourceId())).collect(Collectors.toList());
|
||||
|
||||
if (collect.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
DatasourceResp datasourceResp = collect.get(0);
|
||||
DatasourceDetail datasourceDetail = datasourceResp.getDatasourceDetail();
|
||||
String sqlQuery = datasourceDetail.getSqlQuery();
|
||||
|
||||
DatabaseResp database = databaseService.getDatabase(datasourceResp.getDatabaseId());
|
||||
ModelResp modelResp = modelService.getModel(dimensionReq.getModelId());
|
||||
ModelDetail modelDetail = modelResp.getModelDetail();
|
||||
String sqlQuery = modelDetail.getSqlQuery();
|
||||
DatabaseResp database = databaseService.getDatabase(modelResp.getDatabaseId());
|
||||
|
||||
String sql = "select ai_talk." + dimensionReq.getBizName() + " from (" + sqlQuery
|
||||
+ ") as ai_talk group by ai_talk." + dimensionReq.getBizName();
|
||||
|
||||
@@ -1,39 +1,38 @@
|
||||
package com.tencent.supersonic.semantic.model.application;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.service.UserService;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DomainReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DomainUpdateReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.DomainService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DomainDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.Domain;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DomainRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.DomainConvert;
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Queue;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Objects;
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.assertj.core.util.Sets;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -54,22 +53,16 @@ public class DomainServiceImpl implements DomainService {
|
||||
|
||||
@Override
|
||||
public void createDomain(DomainReq domainReq, User user) {
|
||||
log.info("[create domain] cmd : {}", JSONObject.toJSONString(domainReq));
|
||||
Domain domain = DomainConvert.convert(domainReq);
|
||||
log.info("[create domain] object:{}", JSONObject.toJSONString(domainReq));
|
||||
saveDomain(domain, user);
|
||||
DomainDO domainDO = DomainConvert.convert(domainReq, user);
|
||||
domainDO.setStatus(StatusEnum.ONLINE.getCode());
|
||||
domainRepository.createDomain(domainDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDomain(DomainUpdateReq domainUpdateReq, User user) {
|
||||
domainUpdateReq.updatedBy(user.getName());
|
||||
DomainDO domainDO = getDomainDO(domainUpdateReq.getId());
|
||||
domainDO.setUpdatedAt(new Date());
|
||||
domainDO.setUpdatedBy(user.getName());
|
||||
BeanMapper.mapper(domainUpdateReq, domainDO);
|
||||
domainDO.setAdmin(String.join(",", domainUpdateReq.getAdmins()));
|
||||
domainDO.setAdminOrg(String.join(",", domainUpdateReq.getAdminOrgs()));
|
||||
domainDO.setViewer(String.join(",", domainUpdateReq.getViewers()));
|
||||
domainDO.setViewOrg(String.join(",", domainUpdateReq.getViewOrgs()));
|
||||
domainRepository.updateDomain(domainDO);
|
||||
}
|
||||
|
||||
@@ -161,13 +154,6 @@ public class DomainServiceImpl implements DomainService {
|
||||
return getDomainFullPathMap();
|
||||
}
|
||||
|
||||
//保存并获取自增ID
|
||||
private void saveDomain(Domain domain, User user) {
|
||||
DomainDO domainDO = DomainConvert.convert(domain, user);
|
||||
domainRepository.createDomain(domainDO);
|
||||
domain.setId(domainDO.getId());
|
||||
}
|
||||
|
||||
private List<DomainResp> convertList(List<DomainDO> domainDOS) {
|
||||
List<DomainResp> domainDescs = Lists.newArrayList();
|
||||
if (CollectionUtils.isEmpty(domainDOS)) {
|
||||
|
||||
@@ -6,8 +6,8 @@ import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.DataItem;
|
||||
import com.tencent.supersonic.common.pojo.DataEvent;
|
||||
import com.tencent.supersonic.common.pojo.DataItem;
|
||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.common.pojo.enums.EventType;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
@@ -20,27 +20,17 @@ import com.tencent.supersonic.semantic.api.model.pojo.MetricTypeParams;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetaBatchReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.PageMetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DomainService;
|
||||
import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.MetricDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetricFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.MetricRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.MetricConverter;
|
||||
import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.NameCheckUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -48,6 +38,13 @@ import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -59,8 +56,6 @@ public class MetricServiceImpl implements MetricService {
|
||||
|
||||
private DomainService domainService;
|
||||
|
||||
private DatasourceService datasourceService;
|
||||
|
||||
private ChatGptHelper chatGptHelper;
|
||||
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
@@ -68,13 +63,11 @@ public class MetricServiceImpl implements MetricService {
|
||||
public MetricServiceImpl(MetricRepository metricRepository,
|
||||
ModelService modelService,
|
||||
DomainService domainService,
|
||||
DatasourceService datasourceService,
|
||||
ChatGptHelper chatGptHelper,
|
||||
ApplicationEventPublisher eventPublisher) {
|
||||
this.domainService = domainService;
|
||||
this.metricRepository = metricRepository;
|
||||
this.modelService = modelService;
|
||||
this.datasourceService = datasourceService;
|
||||
this.chatGptHelper = chatGptHelper;
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
@@ -198,21 +191,7 @@ public class MetricServiceImpl implements MetricService {
|
||||
public List<MetricResp> getMetrics(MetaFilter metaFilter) {
|
||||
MetricFilter metricFilter = new MetricFilter();
|
||||
BeanUtils.copyProperties(metaFilter, metricFilter);
|
||||
List<MetricResp> metricResps = convertList(queryMetric(metricFilter));
|
||||
if (metricFilter.getDatasourceId() != null) {
|
||||
return filterByDatasource(metricFilter.getDatasourceId(), metricResps);
|
||||
}
|
||||
return metricResps;
|
||||
}
|
||||
|
||||
private List<MetricResp> filterByDatasource(Long datasourceId, List<MetricResp> metricResps) {
|
||||
return metricResps.stream().filter(metricResp -> {
|
||||
Set<Long> datasourceIdSet = metricResp.getTypeParams().getMeasures().stream()
|
||||
.map(Measure::getDatasourceId)
|
||||
.filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
return !CollectionUtils.isEmpty(datasourceIdSet)
|
||||
&& datasourceIdSet.contains(datasourceId);
|
||||
}).collect(Collectors.toList());
|
||||
return convertList(queryMetric(metricFilter));
|
||||
}
|
||||
|
||||
private void fillAdminRes(List<MetricResp> metricResps, User user) {
|
||||
@@ -257,20 +236,7 @@ public class MetricServiceImpl implements MetricService {
|
||||
if (metricDO == null) {
|
||||
return null;
|
||||
}
|
||||
MetricResp metricResp = MetricConverter.convert2MetricResp(metricDO, new HashMap<>());
|
||||
List<Measure> measures = metricResp.getMeasures();
|
||||
if (CollectionUtils.isEmpty(measures)) {
|
||||
return metricResp;
|
||||
}
|
||||
Map<Long, DatasourceResp> datasourceResps = datasourceService.getDatasourceList().stream()
|
||||
.collect(Collectors.toMap(DatasourceResp::getId, datasourceResp -> datasourceResp));
|
||||
measures.forEach(measure -> {
|
||||
DatasourceResp datasourceResp = datasourceResps.get(measure.getDatasourceId());
|
||||
if (datasourceResp != null) {
|
||||
measure.setDatasourceName(datasourceResp.getName());
|
||||
}
|
||||
});
|
||||
return metricResp;
|
||||
return MetricConverter.convert2MetricResp(metricDO, new HashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.tencent.supersonic.semantic.model.application;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.JoinCondition;
|
||||
import com.tencent.supersonic.common.pojo.ModelRela;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelRelaService;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelRelaDO;
|
||||
import com.tencent.supersonic.semantic.model.infrastructure.mapper.ModelRelaDOMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class ModelRelaServiceImpl
|
||||
extends ServiceImpl<ModelRelaDOMapper, ModelRelaDO> implements ModelRelaService {
|
||||
|
||||
@Override
|
||||
public void save(ModelRela modelRela, User user) {
|
||||
modelRela.createdBy(user.getName());
|
||||
ModelRelaDO modelRelaDO = convert(modelRela);
|
||||
save(modelRelaDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(ModelRela modelRela, User user) {
|
||||
modelRela.updatedBy(user.getName());
|
||||
ModelRelaDO modelRelaDO = convert(modelRela);
|
||||
updateById(modelRelaDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModelRela> getModelRelaList(Long domainId) {
|
||||
QueryWrapper<ModelRelaDO> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().eq(ModelRelaDO::getDomainId, domainId);
|
||||
return list(wrapper).stream().map(this::convert).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModelRela> getModelRela(List<Long> modelIds) {
|
||||
QueryWrapper<ModelRelaDO> wrapper = new QueryWrapper<>();
|
||||
if (CollectionUtils.isEmpty(modelIds)) {
|
||||
wrapper.lambda().in(ModelRelaDO::getFromModelId, modelIds).or()
|
||||
.in(ModelRelaDO::getToModelId, modelIds);
|
||||
}
|
||||
return list(wrapper).stream().map(this::convert).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Long id) {
|
||||
removeById(id);
|
||||
}
|
||||
|
||||
private ModelRela convert(ModelRelaDO modelRelaDO) {
|
||||
ModelRela modelRela = new ModelRela();
|
||||
BeanMapper.mapper(modelRelaDO, modelRela);
|
||||
modelRela.setJoinConditions(JSONObject.parseArray(modelRelaDO.getJoinCondition(), JoinCondition.class));
|
||||
return modelRela;
|
||||
}
|
||||
|
||||
private ModelRelaDO convert(ModelRela modelRelaReq) {
|
||||
ModelRelaDO modelRelaDO = new ModelRelaDO();
|
||||
BeanMapper.mapper(modelRelaReq, modelRelaDO);
|
||||
modelRelaDO.setJoinCondition(JSONObject.toJSONString(modelRelaReq.getJoinConditions()));
|
||||
return modelRelaDO;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,17 +3,25 @@ package com.tencent.supersonic.semantic.model.application;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.service.UserService;
|
||||
import com.tencent.supersonic.common.pojo.DataEvent;
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import com.tencent.supersonic.common.pojo.ModelRela;
|
||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.common.pojo.enums.EventType;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.common.pojo.exception.InvalidArgumentException;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Dim;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ItemDateFilter;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.RelateDimension;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DateInfoReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DimensionReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetaBatchReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||
@@ -22,117 +30,251 @@ import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.Catalog;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DataModelYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.MetricYamlTpl;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatabaseService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DomainService;
|
||||
import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelRelaService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DateInfoDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.manager.DatasourceYamlManager;
|
||||
import com.tencent.supersonic.semantic.model.domain.manager.DimensionYamlManager;
|
||||
import com.tencent.supersonic.semantic.model.domain.manager.MetricYamlManager;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.Datasource;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.DimensionFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetricFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.ModelFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DateInfoRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.ModelRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.ModelConvert;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.DimensionConverter;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.MetricConverter;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.ModelConverter;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.NameCheckUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Slf4j
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ModelServiceImpl implements ModelService {
|
||||
|
||||
private final ModelRepository modelRepository;
|
||||
private final MetricService metricService;
|
||||
private final DimensionService dimensionService;
|
||||
private final DatasourceService datasourceService;
|
||||
private final DomainService domainService;
|
||||
private final UserService userService;
|
||||
private final DatabaseService databaseService;
|
||||
private final Catalog catalog;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
private ModelRepository modelRepository;
|
||||
|
||||
public ModelServiceImpl(ModelRepository modelRepository, @Lazy MetricService metricService,
|
||||
@Lazy DimensionService dimensionService, @Lazy DatasourceService datasourceService,
|
||||
@Lazy DomainService domainService, UserService userService,
|
||||
@Lazy DatabaseService databaseService,
|
||||
@Lazy Catalog catalog, ApplicationEventPublisher eventPublisher) {
|
||||
private DatabaseService databaseService;
|
||||
|
||||
private DimensionService dimensionService;
|
||||
|
||||
private MetricService metricService;
|
||||
|
||||
private DomainService domainService;
|
||||
|
||||
private ModelRelaService modelRelaService;
|
||||
|
||||
private UserService userService;
|
||||
|
||||
private DateInfoRepository dateInfoRepository;
|
||||
|
||||
public ModelServiceImpl(ModelRepository modelRepository,
|
||||
DatabaseService databaseService,
|
||||
@Lazy DimensionService dimensionService,
|
||||
@Lazy MetricService metricService,
|
||||
ModelRelaService modelRelaService,
|
||||
DomainService domainService,
|
||||
UserService userService,
|
||||
DateInfoRepository dateInfoRepository) {
|
||||
this.modelRepository = modelRepository;
|
||||
this.metricService = metricService;
|
||||
this.dimensionService = dimensionService;
|
||||
this.datasourceService = datasourceService;
|
||||
this.domainService = domainService;
|
||||
this.userService = userService;
|
||||
this.databaseService = databaseService;
|
||||
this.catalog = catalog;
|
||||
this.eventPublisher = eventPublisher;
|
||||
this.dimensionService = dimensionService;
|
||||
this.metricService = metricService;
|
||||
this.domainService = domainService;
|
||||
this.modelRelaService = modelRelaService;
|
||||
this.userService = userService;
|
||||
this.dateInfoRepository = dateInfoRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createModel(ModelReq modelReq, User user) {
|
||||
modelReq.createdBy(user.getName());
|
||||
ModelDO modelDO = ModelConvert.convert(modelReq);
|
||||
modelRepository.createModel(modelDO);
|
||||
@Transactional
|
||||
public ModelResp createModel(ModelReq modelReq, User user) throws Exception {
|
||||
checkName(modelReq);
|
||||
ModelDO datasourceDO = ModelConverter.convert(modelReq, user);
|
||||
modelRepository.createModel(datasourceDO);
|
||||
batchCreateDimension(datasourceDO, user);
|
||||
batchCreateMetric(datasourceDO, user);
|
||||
return ModelConverter.convert(datasourceDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateModel(ModelReq modelReq, User user) {
|
||||
ModelDO modelDO = getModelDO(modelReq.getId());
|
||||
modelReq.updatedBy(user.getName());
|
||||
int oldStatus = modelDO.getStatus();
|
||||
BeanMapper.mapper(modelReq, modelDO);
|
||||
if (modelReq.getEntity() != null) {
|
||||
modelDO.setEntity(JsonUtil.toString(modelReq.getEntity()));
|
||||
}
|
||||
if (modelReq.getDrillDownDimensions() != null) {
|
||||
modelDO.setDrillDownDimensions(JsonUtil.toString(modelReq.getDrillDownDimensions()));
|
||||
}
|
||||
@Transactional
|
||||
public ModelResp updateModel(ModelReq modelReq, User user) throws Exception {
|
||||
checkName(modelReq);
|
||||
ModelDO modelDO = modelRepository.getModelById(modelReq.getId());
|
||||
ModelConverter.convert(modelDO, modelReq, user);
|
||||
modelRepository.updateModel(modelDO);
|
||||
statusPublish(oldStatus, modelDO);
|
||||
batchCreateDimension(modelDO, user);
|
||||
batchCreateMetric(modelDO, user);
|
||||
return ModelConverter.convert(modelDO);
|
||||
}
|
||||
|
||||
private void statusPublish(Integer oldStatus, ModelDO modelDO) {
|
||||
if (oldStatus.equals(modelDO.getStatus())) {
|
||||
return;
|
||||
}
|
||||
if (oldStatus.equals(StatusEnum.ONLINE.getCode())
|
||||
&& modelDO.getStatus().equals(StatusEnum.OFFLINE.getCode())) {
|
||||
publishEvent(EventType.DELETE, modelDO);
|
||||
} else if (oldStatus.equals(StatusEnum.OFFLINE.getCode())
|
||||
&& modelDO.getStatus().equals(StatusEnum.ONLINE.getCode())) {
|
||||
publishEvent(EventType.ADD, modelDO);
|
||||
}
|
||||
@Override
|
||||
public List<ModelResp> getModelList(ModelFilter modelFilter) {
|
||||
return ModelConverter.convertList(modelRepository.getModelList(modelFilter));
|
||||
}
|
||||
|
||||
private void publishEvent(EventType eventType, ModelDO modelDO) {
|
||||
eventPublisher.publishEvent(
|
||||
new DataEvent(this, metricService.getDataItems(modelDO.getId()),
|
||||
eventType));
|
||||
eventPublisher.publishEvent(
|
||||
new DataEvent(this, dimensionService.getDataItems(modelDO.getId()),
|
||||
eventType));
|
||||
@Override
|
||||
public Map<Long, ModelResp> getModelMap() {
|
||||
Map<Long, ModelResp> map = new HashMap<>();
|
||||
List<ModelResp> modelResps = getModelList(new ModelFilter());
|
||||
if (CollectionUtils.isEmpty(modelResps)) {
|
||||
return map;
|
||||
}
|
||||
return modelResps.stream().collect(Collectors.toMap(ModelResp::getId, a -> a, (k1, k2) -> k1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteModel(Long id, User user) {
|
||||
ModelDO datasourceDO = modelRepository.getModelById(id);
|
||||
if (datasourceDO == null) {
|
||||
return;
|
||||
}
|
||||
checkDelete(id);
|
||||
ModelDO modelDO = getModelDO(id);
|
||||
modelDO.setStatus(StatusEnum.DELETED.getCode());
|
||||
modelDO.setUpdatedAt(new Date());
|
||||
modelDO.setUpdatedBy(user.getName());
|
||||
modelRepository.updateModel(modelDO);
|
||||
datasourceDO.setStatus(StatusEnum.DELETED.getCode());
|
||||
datasourceDO.setUpdatedAt(new Date());
|
||||
datasourceDO.setUpdatedBy(user.getName());
|
||||
modelRepository.updateModel(datasourceDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemDateResp getItemDate(ItemDateFilter dimension, ItemDateFilter metric) {
|
||||
List<DateInfoReq> itemDates = new ArrayList<>();
|
||||
List<DateInfoDO> dimensions = dateInfoRepository.getDateInfos(dimension);
|
||||
List<DateInfoDO> metrics = dateInfoRepository.getDateInfos(metric);
|
||||
|
||||
log.info("getDateDate, dimension:{}, dimensions dateInfo:{}", dimension, dimensions);
|
||||
log.info("getDateDate, metric:{}, metrics dateInfo:{}", metric, metrics);
|
||||
itemDates.addAll(convert(dimensions));
|
||||
itemDates.addAll(convert(metrics));
|
||||
|
||||
ItemDateResp itemDateDescriptor = calculateDateInternal(itemDates);
|
||||
log.info("itemDateDescriptor:{}", itemDateDescriptor);
|
||||
|
||||
return itemDateDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MeasureResp> getMeasureListOfModel(List<Long> modelIds) {
|
||||
ModelFilter modelFilter = new ModelFilter();
|
||||
modelFilter.setIds(modelIds);
|
||||
List<ModelResp> modelResps = getModelList(modelFilter);
|
||||
return modelResps.stream().flatMap(modelResp -> modelResp.getModelDetail().getMeasures()
|
||||
.stream().map(measure -> ModelConverter.convert(measure, modelResp))).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void batchCreateDimension(ModelDO datasourceDO, User user) throws Exception {
|
||||
List<DimensionReq> dimensionReqs = ModelConverter.convertDimensionList(datasourceDO);
|
||||
dimensionService.createDimensionBatch(dimensionReqs, user);
|
||||
}
|
||||
|
||||
private void batchCreateMetric(ModelDO datasourceDO, User user) throws Exception {
|
||||
List<MetricReq> exprMetricReqs = ModelConverter.convertMetricList(datasourceDO);
|
||||
metricService.createMetricBatch(exprMetricReqs, user);
|
||||
}
|
||||
|
||||
private void checkName(ModelReq modelReq) {
|
||||
if (NameCheckUtils.containsSpecialCharacters(modelReq.getName())) {
|
||||
String message = String.format("模型名称[%s]包含特殊字符, 请修改", modelReq.getName());
|
||||
throw new InvalidArgumentException(message);
|
||||
}
|
||||
List<Dim> dims = modelReq.getModelDetail().getDimensions();
|
||||
List<Measure> measures = modelReq.getModelDetail().getMeasures();
|
||||
List<Dim> timeDims = modelReq.getTimeDimension();
|
||||
List<Identify> identifies = modelReq.getModelDetail().getIdentifiers();
|
||||
if (CollectionUtils.isEmpty(dims)) {
|
||||
throw new InvalidArgumentException("缺少维度信息");
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(measures) && CollectionUtils.isEmpty(timeDims)) {
|
||||
throw new InvalidArgumentException("有度量时, 不可缺少时间维度");
|
||||
}
|
||||
for (Measure measure : measures) {
|
||||
if (StringUtils.isNotBlank(measure.getName())
|
||||
&& NameCheckUtils.containsSpecialCharacters(measure.getName())) {
|
||||
String message = String.format("度量[%s]包含特殊字符, 请修改", measure.getName());
|
||||
throw new InvalidArgumentException(message);
|
||||
}
|
||||
}
|
||||
for (Dim dim : dims) {
|
||||
if (StringUtils.isNotBlank(dim.getName())
|
||||
&& NameCheckUtils.containsSpecialCharacters(dim.getName())) {
|
||||
String message = String.format("维度[%s]包含特殊字符, 请修改", dim.getName());
|
||||
throw new InvalidArgumentException(message);
|
||||
}
|
||||
}
|
||||
for (Identify identify : identifies) {
|
||||
if (StringUtils.isNotBlank(identify.getName())
|
||||
&& NameCheckUtils.containsSpecialCharacters(identify.getName())) {
|
||||
String message = String.format("主键/外键[%s]包含特殊字符, 请修改", identify.getName());
|
||||
throw new InvalidArgumentException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkDelete(Long modelId) {
|
||||
MetaFilter metaFilter = new MetaFilter();
|
||||
metaFilter.setModelIds(Lists.newArrayList(modelId));
|
||||
List<MetricResp> metricResps = metricService.getMetrics(metaFilter);
|
||||
List<DimensionResp> dimensionResps = dimensionService.getDimensions(metaFilter);
|
||||
if (!CollectionUtils.isEmpty(metricResps) || !CollectionUtils.isEmpty(dimensionResps)) {
|
||||
throw new RuntimeException("存在基于该模型创建的指标和维度, 暂不能删除, 请确认");
|
||||
}
|
||||
}
|
||||
|
||||
private ItemDateResp calculateDateInternal(List<DateInfoReq> itemDates) {
|
||||
if (CollectionUtils.isEmpty(itemDates)) {
|
||||
log.warn("itemDates is empty!");
|
||||
return null;
|
||||
}
|
||||
String dateFormat = itemDates.get(0).getDateFormat();
|
||||
String startDate = itemDates.get(0).getStartDate();
|
||||
String endDate = itemDates.get(0).getEndDate();
|
||||
String datePeriod = itemDates.get(0).getDatePeriod();
|
||||
List<String> unavailableDateList = itemDates.get(0).getUnavailableDateList();
|
||||
for (DateInfoReq item : itemDates) {
|
||||
String startDate1 = item.getStartDate();
|
||||
String endDate1 = item.getEndDate();
|
||||
List<String> unavailableDateList1 = item.getUnavailableDateList();
|
||||
if (Strings.isNotEmpty(startDate1) && startDate1.compareTo(startDate) > 0) {
|
||||
startDate = startDate1;
|
||||
}
|
||||
if (Strings.isNotEmpty(endDate1) && endDate1.compareTo(endDate) < 0) {
|
||||
endDate = endDate1;
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(unavailableDateList1)) {
|
||||
unavailableDateList.addAll(unavailableDateList1);
|
||||
}
|
||||
}
|
||||
|
||||
return new ItemDateResp(dateFormat, startDate, endDate, datePeriod, unavailableDateList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,7 +287,8 @@ public class ModelServiceImpl implements ModelService {
|
||||
modelRespSet = modelRespSet.stream().filter(modelResp ->
|
||||
modelResp.getDomainId().equals(domainId)).collect(Collectors.toSet());
|
||||
}
|
||||
return fillMetricInfo(new ArrayList<>(modelRespSet));
|
||||
return fillMetricInfo(new ArrayList<>(modelRespSet)).stream()
|
||||
.sorted(Comparator.comparingLong(SchemaItem::getId)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<ModelResp> getModelRespAuthInheritDomain(User user, AuthType authType) {
|
||||
@@ -153,7 +296,7 @@ public class ModelServiceImpl implements ModelService {
|
||||
if (CollectionUtils.isEmpty(domainResps)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
List<ModelResp> allModelList = getModelList();
|
||||
List<ModelResp> allModelList = getModelList(new ModelFilter());
|
||||
Set<Long> domainIds = domainResps.stream().map(DomainResp::getId).collect(Collectors.toSet());
|
||||
return allModelList.stream().filter(modelResp ->
|
||||
domainIds.contains(modelResp.getDomainId())).collect(Collectors.toList());
|
||||
@@ -161,7 +304,7 @@ public class ModelServiceImpl implements ModelService {
|
||||
|
||||
@Override
|
||||
public List<ModelResp> getModelAuthList(User user, AuthType authTypeEnum) {
|
||||
List<ModelResp> modelResps = getModelList();
|
||||
List<ModelResp> modelResps = getModelList(new ModelFilter());
|
||||
Set<String> orgIds = userService.getUserAllOrgId(user.getName());
|
||||
List<ModelResp> modelWithAuth = Lists.newArrayList();
|
||||
if (authTypeEnum.equals(AuthType.ADMIN)) {
|
||||
@@ -182,7 +325,9 @@ public class ModelServiceImpl implements ModelService {
|
||||
if (CollectionUtils.isEmpty(domainIds)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
List<ModelResp> modelResps = getModelList();
|
||||
ModelFilter modelFilter = new ModelFilter();
|
||||
modelFilter.setDomainIds(domainIds);
|
||||
List<ModelResp> modelResps = getModelList(modelFilter);
|
||||
if (CollectionUtils.isEmpty(modelResps)) {
|
||||
return modelResps;
|
||||
}
|
||||
@@ -190,75 +335,15 @@ public class ModelServiceImpl implements ModelService {
|
||||
domainIds.contains(modelResp.getDomainId())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<ModelResp> getModelList(List<Long> modelIds) {
|
||||
return getModelList().stream()
|
||||
.filter(modelDO -> modelIds.contains(modelDO.getId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModelResp> getModelList() {
|
||||
return convertList(modelRepository.getModelList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelResp getModel(Long id) {
|
||||
ModelDO modelDO = getModelDO(id);
|
||||
if (modelDO == null) {
|
||||
return null;
|
||||
}
|
||||
Map<Long, DomainResp> domainRespMap = domainService.getDomainList().stream()
|
||||
.collect(Collectors.toMap(DomainResp::getId, d -> d));
|
||||
return ModelConvert.convert(getModelDO(id), domainRespMap);
|
||||
}
|
||||
|
||||
private void checkDelete(Long id) {
|
||||
MetaFilter metaFilter = new MetaFilter(Lists.newArrayList(id));
|
||||
List<MetricResp> metricResps = metricService.getMetrics(metaFilter);
|
||||
List<DimensionResp> dimensionResps = dimensionService.getDimensions(metaFilter);
|
||||
List<DatasourceResp> datasourceResps = datasourceService.getDatasourceList(id);
|
||||
if (!CollectionUtils.isEmpty(metricResps) || !CollectionUtils.isEmpty(datasourceResps)
|
||||
|| !CollectionUtils.isEmpty(dimensionResps)) {
|
||||
throw new RuntimeException("该模型下存在数据源、指标或者维度, 暂不能删除, 请确认");
|
||||
}
|
||||
}
|
||||
|
||||
private List<ModelResp> convertList(List<ModelDO> modelDOS) {
|
||||
List<ModelResp> modelResps = Lists.newArrayList();
|
||||
if (CollectionUtils.isEmpty(modelDOS)) {
|
||||
return modelResps;
|
||||
}
|
||||
Map<Long, DomainResp> domainRespMap = domainService.getDomainList()
|
||||
.stream().collect(Collectors.toMap(DomainResp::getId, d -> d));
|
||||
return modelDOS.stream()
|
||||
.map(modelDO -> ModelConvert.convert(modelDO, domainRespMap))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<ModelResp> fillMetricInfo(List<ModelResp> modelResps) {
|
||||
if (CollectionUtils.isEmpty(modelResps)) {
|
||||
return modelResps;
|
||||
}
|
||||
Map<Long, List<MetricResp>> metricMap = metricService.getMetrics(new MetricFilter()).stream()
|
||||
.collect(Collectors.groupingBy(MetricResp::getModelId));
|
||||
Map<Long, List<DimensionResp>> dimensionMap = dimensionService.getDimensions(new DimensionFilter()).stream()
|
||||
.collect(Collectors.groupingBy(DimensionResp::getModelId));
|
||||
modelResps.forEach(modelResp -> {
|
||||
modelResp.setDimensionCnt(dimensionMap.getOrDefault(modelResp.getId(), Lists.newArrayList()).size());
|
||||
modelResp.setMetricCnt(metricMap.getOrDefault(modelResp.getId(), Lists.newArrayList()).size());
|
||||
});
|
||||
return modelResps;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<Long, ModelResp> getModelMap() {
|
||||
return getModelList().stream().collect(Collectors.toMap(ModelResp::getId, a -> a, (k1, k2) -> k1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, String> getModelFullPathMap() {
|
||||
return getModelList().stream().filter(m -> m != null && m.getFullPath() != null)
|
||||
.collect(Collectors.toMap(ModelResp::getId,
|
||||
ModelResp::getFullPath, (k1, k2) -> k1));
|
||||
return ModelConverter.convert(modelDO, domainRespMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -282,12 +367,9 @@ public class ModelServiceImpl implements ModelService {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
|
||||
protected ModelDO getModelDO(Long id) {
|
||||
return modelRepository.getModelById(id);
|
||||
}
|
||||
|
||||
private ModelSchemaResp fetchSingleModelSchema(ModelResp modelResp) {
|
||||
Long modelId = modelResp.getId();
|
||||
@Override
|
||||
public ModelSchemaResp fetchSingleModelSchema(Long modelId) {
|
||||
ModelResp modelResp = getModel(modelId);
|
||||
ModelSchemaResp modelSchemaResp = new ModelSchemaResp();
|
||||
BeanUtils.copyProperties(modelResp, modelSchemaResp);
|
||||
modelSchemaResp.setDimensions(generateDimSchema(modelId));
|
||||
@@ -295,12 +377,6 @@ public class ModelServiceImpl implements ModelService {
|
||||
return modelSchemaResp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelSchemaResp fetchSingleModelSchema(Long modelId) {
|
||||
ModelResp model = getModel(modelId);
|
||||
return fetchSingleModelSchema(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModelSchemaResp> fetchModelSchema(ModelSchemaFilterReq modelSchemaFilterReq) {
|
||||
List<ModelSchemaResp> modelSchemaRespList = new ArrayList<>();
|
||||
@@ -314,23 +390,24 @@ public class ModelServiceImpl implements ModelService {
|
||||
.stream().collect(Collectors.groupingBy(MetricResp::getModelId));
|
||||
Map<Long, List<DimensionResp>> dimensionRespsMap = dimensionService.getDimensions(metaFilter)
|
||||
.stream().collect(Collectors.groupingBy(DimensionResp::getModelId));
|
||||
Map<Long, List<MeasureResp>> measureRespsMap = datasourceService.getMeasureListOfModel(modelIds)
|
||||
.stream().collect(Collectors.groupingBy(MeasureResp::getModelId));
|
||||
List<ModelRela> modelRelas = modelRelaService.getModelRela(modelIds);
|
||||
for (Long modelId : modelIds) {
|
||||
ModelResp modelResp = getModelMap().get(modelId);
|
||||
if (modelResp == null || !StatusEnum.ONLINE.getCode().equals(modelResp.getStatus())) {
|
||||
continue;
|
||||
}
|
||||
List<MeasureResp> measureResps = measureRespsMap.getOrDefault(modelId, Lists.newArrayList());
|
||||
List<MetricResp> metricResps = metricRespMap.getOrDefault(modelId, Lists.newArrayList());
|
||||
List<MetricSchemaResp> metricSchemaResps = metricResps.stream().map(metricResp ->
|
||||
convert(metricResp, metricResps, measureResps, modelResp)).collect(Collectors.toList());
|
||||
convert(metricResp, modelResp)).collect(Collectors.toList());
|
||||
List<DimSchemaResp> dimensionResps = dimensionRespsMap.getOrDefault(modelId, Lists.newArrayList())
|
||||
.stream().map(this::convert).collect(Collectors.toList());
|
||||
ModelSchemaResp modelSchemaResp = new ModelSchemaResp();
|
||||
BeanUtils.copyProperties(modelResp, modelSchemaResp);
|
||||
modelSchemaResp.setDimensions(dimensionResps);
|
||||
modelSchemaResp.setMetrics(metricSchemaResps);
|
||||
modelSchemaResp.setModelRelas(modelRelas.stream().filter(modelRela
|
||||
-> modelRela.getFromModelId().equals(modelId) || modelRela.getToModelId().equals(modelId))
|
||||
.collect(Collectors.toList()));
|
||||
modelSchemaRespList.add(modelSchemaResp);
|
||||
}
|
||||
return modelSchemaRespList;
|
||||
@@ -338,20 +415,58 @@ public class ModelServiceImpl implements ModelService {
|
||||
|
||||
@Override
|
||||
public DatabaseResp getDatabaseByModelId(Long modelId) {
|
||||
List<DatasourceResp> datasourceResps = datasourceService.getDatasourceList(modelId);
|
||||
if (!CollectionUtils.isEmpty(datasourceResps)) {
|
||||
Long databaseId = datasourceResps.iterator().next().getDatabaseId();
|
||||
ModelResp modelResp = getModel(modelId);
|
||||
if (modelResp != null) {
|
||||
Long databaseId = modelResp.getDatabaseId();
|
||||
return databaseService.getDatabase(databaseId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchUpdateStatus(MetaBatchReq metaBatchReq, User user) {
|
||||
if (CollectionUtils.isEmpty(metaBatchReq.getIds())) {
|
||||
return;
|
||||
}
|
||||
ModelFilter modelFilter = new ModelFilter();
|
||||
modelFilter.setIds(metaBatchReq.getIds());
|
||||
List<ModelDO> modelDOS = modelRepository.getModelList(modelFilter);
|
||||
if (CollectionUtils.isEmpty(modelDOS)) {
|
||||
return;
|
||||
}
|
||||
modelDOS = modelDOS.stream()
|
||||
.peek(modelDO -> {
|
||||
modelDO.setStatus(metaBatchReq.getStatus());
|
||||
modelDO.setUpdatedAt(new Date());
|
||||
modelDO.setUpdatedBy(user.getName());
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
modelRepository.batchUpdate(modelDOS);
|
||||
}
|
||||
|
||||
private List<ModelResp> fillMetricInfo(List<ModelResp> modelResps) {
|
||||
if (CollectionUtils.isEmpty(modelResps)) {
|
||||
return modelResps;
|
||||
}
|
||||
Map<Long, List<MetricResp>> metricMap = metricService.getMetrics(new MetricFilter()).stream()
|
||||
.collect(Collectors.groupingBy(MetricResp::getModelId));
|
||||
Map<Long, List<DimensionResp>> dimensionMap = dimensionService.getDimensions(new DimensionFilter()).stream()
|
||||
.collect(Collectors.groupingBy(DimensionResp::getModelId));
|
||||
modelResps.forEach(modelResp -> {
|
||||
modelResp.setDimensionCnt(dimensionMap.getOrDefault(modelResp.getId(), Lists.newArrayList()).size());
|
||||
modelResp.setMetricCnt(metricMap.getOrDefault(modelResp.getId(), Lists.newArrayList()).size());
|
||||
});
|
||||
return modelResps;
|
||||
}
|
||||
|
||||
protected ModelDO getModelDO(Long id) {
|
||||
return modelRepository.getModelById(id);
|
||||
}
|
||||
|
||||
private List<MetricSchemaResp> generateMetricSchema(Long modelId, ModelResp modelResp) {
|
||||
List<MetricSchemaResp> metricSchemaDescList = new ArrayList<>();
|
||||
List<MetricResp> metricResps = metricService.getMetrics(new MetaFilter(Lists.newArrayList(modelId)));
|
||||
List<MeasureResp> measureResps = datasourceService.getMeasureListOfModel(Lists.newArrayList(modelId));
|
||||
metricResps.stream().forEach(metricResp ->
|
||||
metricSchemaDescList.add(convert(metricResp, metricResps, measureResps, modelResp)));
|
||||
metricResps.forEach(metricResp -> metricSchemaDescList.add(convert(metricResp, modelResp)));
|
||||
return metricSchemaDescList;
|
||||
}
|
||||
|
||||
@@ -367,8 +482,7 @@ public class ModelServiceImpl implements ModelService {
|
||||
return dimSchemaResp;
|
||||
}
|
||||
|
||||
private MetricSchemaResp convert(MetricResp metricResp, List<MetricResp> metricResps,
|
||||
List<MeasureResp> measureResps, ModelResp modelResp) {
|
||||
private MetricSchemaResp convert(MetricResp metricResp, ModelResp modelResp) {
|
||||
MetricSchemaResp metricSchemaResp = new MetricSchemaResp();
|
||||
BeanUtils.copyProperties(metricResp, metricSchemaResp);
|
||||
RelateDimension relateDimension = metricResp.getRelateDimension();
|
||||
@@ -377,11 +491,20 @@ public class ModelServiceImpl implements ModelService {
|
||||
.drillDownDimensions(modelResp.getDrillDownDimensions()).build());
|
||||
}
|
||||
metricSchemaResp.setUseCnt(0L);
|
||||
String agg = catalog.getAgg(metricResps, measureResps, metricSchemaResp.getBizName());
|
||||
metricSchemaResp.setDefaultAgg(agg);
|
||||
return metricSchemaResp;
|
||||
}
|
||||
|
||||
private List<DateInfoReq> convert(List<DateInfoDO> dateInfoDOList) {
|
||||
List<DateInfoReq> dateInfoCommendList = new ArrayList<>();
|
||||
dateInfoDOList.forEach(dateInfoDO -> {
|
||||
DateInfoReq dateInfoCommend = new DateInfoReq();
|
||||
BeanUtils.copyProperties(dateInfoDO, dateInfoCommend);
|
||||
dateInfoCommend.setUnavailableDateList(JsonUtil.toList(dateInfoDO.getUnavailableDateList(), String.class));
|
||||
dateInfoCommendList.add(dateInfoCommend);
|
||||
});
|
||||
return dateInfoCommendList;
|
||||
}
|
||||
|
||||
private List<Long> generateModelIdsReq(ModelSchemaFilterReq filter) {
|
||||
if (Objects.nonNull(filter) && !CollectionUtils.isEmpty(filter.getModelIds())) {
|
||||
return filter.getModelIds();
|
||||
@@ -411,9 +534,10 @@ public class ModelServiceImpl implements ModelService {
|
||||
}
|
||||
|
||||
public static boolean checkViewerPermission(Set<String> orgIds, User user, ModelResp modelResp) {
|
||||
List<String> admins = modelResp.getAdmins();
|
||||
if (checkAdminPermission(orgIds, user, modelResp)) {
|
||||
return true;
|
||||
}
|
||||
List<String> viewers = modelResp.getViewers();
|
||||
List<String> adminOrgs = modelResp.getAdminOrgs();
|
||||
List<String> viewOrgs = modelResp.getViewOrgs();
|
||||
if (user.isSuperAdmin()) {
|
||||
return true;
|
||||
@@ -422,17 +546,12 @@ public class ModelServiceImpl implements ModelService {
|
||||
return true;
|
||||
}
|
||||
String userName = user.getName();
|
||||
if (admins.contains(userName) || viewers.contains(userName) || modelResp.getCreatedBy().equals(userName)) {
|
||||
if (viewers.contains(userName) || modelResp.getCreatedBy().equals(userName)) {
|
||||
return true;
|
||||
}
|
||||
if (CollectionUtils.isEmpty(adminOrgs) && CollectionUtils.isEmpty(viewOrgs)) {
|
||||
if (CollectionUtils.isEmpty(viewOrgs)) {
|
||||
return false;
|
||||
}
|
||||
for (String orgId : orgIds) {
|
||||
if (adminOrgs.contains(orgId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (String orgId : orgIds) {
|
||||
if (viewOrgs.contains(orgId)) {
|
||||
return true;
|
||||
@@ -440,4 +559,43 @@ public class ModelServiceImpl implements ModelService {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void getModelYamlTplByModelIds(Set<Long> modelIds, Map<String, List<DimensionYamlTpl>> dimensionYamlMap,
|
||||
List<DataModelYamlTpl> dataModelYamlTplList, List<MetricYamlTpl> metricYamlTplList,
|
||||
Map<Long, String> modelIdName) {
|
||||
for (Long modelId : modelIds) {
|
||||
ModelResp modelResp = getModel(modelId);
|
||||
modelIdName.put(modelId, modelResp.getBizName());
|
||||
MetaFilter metaFilter = new MetaFilter(Lists.newArrayList(modelId));
|
||||
List<MetricResp> metricResps = metricService.getMetrics(metaFilter);
|
||||
metricYamlTplList.addAll(MetricYamlManager.convert2YamlObj(MetricConverter.metricInfo2Metric(metricResps)));
|
||||
Long databaseId = modelResp.getDatabaseId();
|
||||
DatabaseResp databaseResp = databaseService.getDatabase(databaseId);
|
||||
List<DimensionResp> dimensionResps = dimensionService.getDimensions(metaFilter);
|
||||
|
||||
dataModelYamlTplList.add(DatasourceYamlManager.convert2YamlObj(
|
||||
datasourceInfo2Datasource(modelResp), databaseResp));
|
||||
if (!dimensionYamlMap.containsKey(modelResp.getBizName())) {
|
||||
dimensionYamlMap.put(modelResp.getBizName(), new ArrayList<>());
|
||||
}
|
||||
List<DimensionResp> dimensionRespList = dimensionResps.stream()
|
||||
.filter(d -> d.getModelBizName().equalsIgnoreCase(modelResp.getBizName()))
|
||||
.collect(Collectors.toList());
|
||||
dimensionYamlMap.get(modelResp.getBizName()).addAll(DimensionYamlManager.convert2DimensionYaml(
|
||||
DimensionConverter.dimensionInfo2Dimension(dimensionRespList)));
|
||||
}
|
||||
}
|
||||
|
||||
public static Datasource datasourceInfo2Datasource(ModelResp modelResp) {
|
||||
Datasource datasource = new Datasource();
|
||||
BeanUtils.copyProperties(modelResp, datasource);
|
||||
datasource.setDatasourceDetail(modelResp.getModelDetail());
|
||||
datasource.setModelId(modelResp.getId());
|
||||
datasource.setDatabaseId(modelResp.getDatabaseId());
|
||||
return datasource;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,63 +1,64 @@
|
||||
package com.tencent.supersonic.semantic.model.application;
|
||||
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ViewInfoReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaRelaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ViewInfoDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.ViewInfoRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaRelaResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ViewInfoDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.ModelFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.ViewInfoRepository;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ViewInfoServiceImpl {
|
||||
|
||||
private ViewInfoRepository viewInfoRepository;
|
||||
|
||||
private DatasourceService datasourceService;
|
||||
private ModelService modelService;
|
||||
|
||||
private DimensionService dimensionService;
|
||||
|
||||
private MetricService metricService;
|
||||
|
||||
public ViewInfoServiceImpl(ViewInfoRepository viewInfoRepository, DatasourceService datasourceService,
|
||||
public ViewInfoServiceImpl(ViewInfoRepository viewInfoRepository, ModelService modelService,
|
||||
MetricService metricService, DimensionService dimensionService) {
|
||||
this.viewInfoRepository = viewInfoRepository;
|
||||
this.dimensionService = dimensionService;
|
||||
this.metricService = metricService;
|
||||
this.datasourceService = datasourceService;
|
||||
this.modelService = modelService;
|
||||
}
|
||||
|
||||
public List<ViewInfoDO> getViewInfoList(Long modelId) {
|
||||
return viewInfoRepository.getViewInfoList(modelId);
|
||||
}
|
||||
|
||||
public List<ModelSchemaRelaResp> getDomainSchema(Long modelId) {
|
||||
public List<ModelSchemaRelaResp> getDomainSchema(Long domainId) {
|
||||
List<ModelSchemaRelaResp> domainSchemaRelaResps = Lists.newArrayList();
|
||||
List<DatasourceResp> datasourceResps = datasourceService.getDatasourceList(modelId);
|
||||
for (DatasourceResp datasourceResp : datasourceResps) {
|
||||
ModelFilter modelFilter = new ModelFilter();
|
||||
modelFilter.setDomainIds(Lists.newArrayList(domainId));
|
||||
List<ModelResp> modelResps = modelService.getModelList(modelFilter);
|
||||
for (ModelResp modelResp : modelResps) {
|
||||
ModelSchemaRelaResp domainSchemaRelaResp = new ModelSchemaRelaResp();
|
||||
Long datasourceId = datasourceResp.getId();
|
||||
MetaFilter metaFilter = new MetaFilter();
|
||||
metaFilter.setModelIds(Lists.newArrayList(modelId));
|
||||
metaFilter.setDatasourceId(datasourceId);
|
||||
metaFilter.setModelIds(Lists.newArrayList(modelResp.getId()));
|
||||
List<MetricResp> metricResps = metricService.getMetrics(metaFilter);
|
||||
List<DimensionResp> dimensionResps = dimensionService.getDimensions(metaFilter);
|
||||
domainSchemaRelaResp.setDatasource(datasourceResp);
|
||||
domainSchemaRelaResp.setModel(modelResp);
|
||||
domainSchemaRelaResp.setDimensions(dimensionResps);
|
||||
domainSchemaRelaResp.setMetrics(metricResps);
|
||||
domainSchemaRelaResp.setDomainId(modelId);
|
||||
domainSchemaRelaResp.setDomainId(domainId);
|
||||
domainSchemaRelaResps.add(domainSchemaRelaResp);
|
||||
}
|
||||
return domainSchemaRelaResps;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package com.tencent.supersonic.semantic.model.domain;
|
||||
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import com.tencent.supersonic.common.pojo.ModelRela;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ItemDateFilter;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DatasourceYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DataModelYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.MetricYamlTpl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -20,24 +20,23 @@ public interface Catalog {
|
||||
|
||||
DatabaseResp getDatabaseByModelId(Long modelId);
|
||||
|
||||
List<DatasourceResp> getDatasourceList(Long modelId);
|
||||
|
||||
String getModelFullPath(Long modelId);
|
||||
|
||||
Map<Long, String> getModelFullPath();
|
||||
String getModelFullPath(List<Long> modelIds);
|
||||
|
||||
DimensionResp getDimension(String bizName, Long modelId);
|
||||
|
||||
List<DimensionResp> getDimensions(Long modelId);
|
||||
List<DimensionResp> getDimensions(List<Long> modelIds);
|
||||
|
||||
List<MetricResp> getMetrics(Long modelId);
|
||||
List<MetricResp> getMetrics(List<Long> modelIds);
|
||||
|
||||
List<ModelRela> getModelRela(List<Long> modelIds);
|
||||
|
||||
void getModelYamlTplByModelIds(Set<Long> modelIds, Map<String, List<DimensionYamlTpl>> dimensionYamlMap,
|
||||
List<DatasourceYamlTpl> datasourceYamlTplList, List<MetricYamlTpl> metricYamlTplList);
|
||||
List<DataModelYamlTpl> dataModelYamlTplList, List<MetricYamlTpl> metricYamlTplList,
|
||||
Map<Long, String> modelIdName);
|
||||
|
||||
|
||||
ItemDateResp getItemDate(ItemDateFilter dimension, ItemDateFilter metric);
|
||||
|
||||
String getAgg(List<MetricResp> metricResps, List<MeasureResp> measureRespList, String metricBizName);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.model.domain;
|
||||
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ItemDateFilter;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DatasourceYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.MetricYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DatasourceReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public interface DatasourceService {
|
||||
|
||||
DatasourceResp createDatasource(DatasourceReq datasourceReq, User user) throws Exception;
|
||||
|
||||
DatasourceResp updateDatasource(DatasourceReq datasourceReq, User user) throws Exception;
|
||||
|
||||
List<DatasourceResp> getDatasourceListNoMeasurePrefix(Long modelId);
|
||||
|
||||
List<DatasourceResp> getDatasourceList();
|
||||
|
||||
List<DatasourceResp> getDatasourceList(Long modelId);
|
||||
|
||||
List<DatasourceResp> getDatasourceByDatabase(Long databaseId);
|
||||
|
||||
Map<Long, DatasourceResp> getDatasourceMap();
|
||||
|
||||
void deleteDatasource(Long id, User user);
|
||||
|
||||
ItemDateResp getItemDate(ItemDateFilter dimension, ItemDateFilter metric);
|
||||
|
||||
List<MeasureResp> getMeasureListOfModel(List<Long> modelIds);
|
||||
|
||||
void getModelYamlTplByModelIds(Set<Long> modelIds, Map<String, List<DimensionYamlTpl>> dimensionYamlMap,
|
||||
List<DatasourceYamlTpl> datasourceYamlTplList, List<MetricYamlTpl> metricYamlTplList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.tencent.supersonic.semantic.model.domain;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.ModelRela;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ModelRelaService {
|
||||
|
||||
|
||||
void save(ModelRela modelRela, User user);
|
||||
|
||||
void update(ModelRela modelRela, User user);
|
||||
|
||||
List<ModelRela> getModelRelaList(Long domainId);
|
||||
|
||||
List<ModelRela> getModelRela(List<Long> modelIds);
|
||||
|
||||
void delete(Long id);
|
||||
}
|
||||
@@ -1,39 +1,48 @@
|
||||
package com.tencent.supersonic.semantic.model.domain;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ItemDateFilter;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetaBatchReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DataModelYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.MetricYamlTpl;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.ModelFilter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public interface ModelService {
|
||||
|
||||
ModelResp createModel(ModelReq datasourceReq, User user) throws Exception;
|
||||
|
||||
ModelResp updateModel(ModelReq datasourceReq, User user) throws Exception;
|
||||
|
||||
List<ModelResp> getModelList(ModelFilter modelFilter);
|
||||
|
||||
Map<Long, ModelResp> getModelMap();
|
||||
|
||||
void deleteModel(Long id, User user);
|
||||
|
||||
ItemDateResp getItemDate(ItemDateFilter dimension, ItemDateFilter metric);
|
||||
|
||||
List<MeasureResp> getMeasureListOfModel(List<Long> modelIds);
|
||||
|
||||
List<ModelResp> getModelListWithAuth(User user, Long domainId, AuthType authType);
|
||||
|
||||
List<ModelResp> getModelAuthList(User user, AuthType authTypeEnum);
|
||||
|
||||
List<ModelResp> getModelByDomainIds(List<Long> domainIds);
|
||||
|
||||
List<ModelResp> getModelList();
|
||||
|
||||
List<ModelResp> getModelList(List<Long> modelIds);
|
||||
|
||||
ModelResp getModel(Long id);
|
||||
|
||||
void updateModel(ModelReq modelReq, User user);
|
||||
|
||||
void createModel(ModelReq modelReq, User user);
|
||||
|
||||
void deleteModel(Long id, User user);
|
||||
|
||||
Map<Long, ModelResp> getModelMap();
|
||||
|
||||
Map<Long, String> getModelFullPathMap();
|
||||
|
||||
List<String> getModelAdmin(Long id);
|
||||
|
||||
ModelSchemaResp fetchSingleModelSchema(Long modelId);
|
||||
@@ -41,4 +50,11 @@ public interface ModelService {
|
||||
List<ModelSchemaResp> fetchModelSchema(ModelSchemaFilterReq modelSchemaFilterReq);
|
||||
|
||||
DatabaseResp getDatabaseByModelId(Long modelId);
|
||||
|
||||
void batchUpdateStatus(MetaBatchReq metaBatchReq, User user);
|
||||
|
||||
void getModelYamlTplByModelIds(Set<Long> modelIds, Map<String, List<DimensionYamlTpl>> dimensionYamlMap,
|
||||
List<DataModelYamlTpl> dataModelYamlTplList, List<MetricYamlTpl> metricYamlTplList,
|
||||
Map<Long, String> modelIdName);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.dataobject;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("s2_datasource")
|
||||
public class DatasourceDO {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 模型ID
|
||||
*/
|
||||
private Long modelId;
|
||||
|
||||
/**
|
||||
* 数据源名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 内部名称
|
||||
*/
|
||||
private String bizName;
|
||||
|
||||
/**
|
||||
* 数据源描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 数据库实例ID
|
||||
*/
|
||||
private Long databaseId;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createdAt;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String createdBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updatedAt;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
private String updatedBy;
|
||||
|
||||
/**
|
||||
* 数据源配置
|
||||
*/
|
||||
private String datasourceDetail;
|
||||
|
||||
/**
|
||||
* 上游依赖标识
|
||||
*/
|
||||
private String depends;
|
||||
|
||||
private String filterSql;
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,105 +9,44 @@ import java.util.Date;
|
||||
@Data
|
||||
@TableName("s2_dimension")
|
||||
public class DimensionDO {
|
||||
/**
|
||||
* 维度ID
|
||||
*/
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 主题域id
|
||||
*/
|
||||
private Long modelId;
|
||||
|
||||
/**
|
||||
* 所属数据源id
|
||||
*/
|
||||
private Long datasourceId;
|
||||
|
||||
/**
|
||||
* 维度名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 字段名称
|
||||
*/
|
||||
private String bizName;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 维度状态,0正常,1下架,2删除
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 敏感级别
|
||||
*/
|
||||
private Integer sensitiveLevel;
|
||||
|
||||
/**
|
||||
* 维度类型 categorical,time
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createdAt;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String createdBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updatedAt;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
private String updatedBy;
|
||||
|
||||
/**
|
||||
* 语义类型DATE, ID, CATEGORY
|
||||
*/
|
||||
private String semanticType;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String alias;
|
||||
|
||||
/**
|
||||
* default values of dimension when query
|
||||
*/
|
||||
private String defaultValues;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String dimValueMaps;
|
||||
|
||||
/**
|
||||
* 类型参数
|
||||
*/
|
||||
private String typeParams;
|
||||
|
||||
/**
|
||||
* 表达式
|
||||
*/
|
||||
private String expr;
|
||||
|
||||
/**
|
||||
* 数据类型
|
||||
*/
|
||||
private String dataType;
|
||||
|
||||
private int isTag;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,19 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.dataobject;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("s2_domain")
|
||||
public class DomainDO {
|
||||
/**
|
||||
* 自增ID
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
@@ -73,227 +81,4 @@ public class DomainDO {
|
||||
*/
|
||||
private String viewOrg;
|
||||
|
||||
/**
|
||||
* 自增ID
|
||||
* @return id 自增ID
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自增ID
|
||||
* @param id 自增ID
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域名称
|
||||
* @return name 主题域名称
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域名称
|
||||
* @param name 主题域名称
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name == null ? null : name.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部名称
|
||||
* @return biz_name 内部名称
|
||||
*/
|
||||
public String getBizName() {
|
||||
return bizName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部名称
|
||||
* @param bizName 内部名称
|
||||
*/
|
||||
public void setBizName(String bizName) {
|
||||
this.bizName = bizName == null ? null : bizName.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 父主题域ID
|
||||
* @return parent_id 父主题域ID
|
||||
*/
|
||||
public Long getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 父主题域ID
|
||||
* @param parentId 父主题域ID
|
||||
*/
|
||||
public void setParentId(Long parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域状态
|
||||
* @return status 主题域状态
|
||||
*/
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域状态
|
||||
* @param status 主题域状态
|
||||
*/
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
* @return created_at 创建时间
|
||||
*/
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
* @param createdAt 创建时间
|
||||
*/
|
||||
public void setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
* @return created_by 创建人
|
||||
*/
|
||||
public String getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
* @param createdBy 创建人
|
||||
*/
|
||||
public void setCreatedBy(String createdBy) {
|
||||
this.createdBy = createdBy == null ? null : createdBy.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
* @return updated_at 更新时间
|
||||
*/
|
||||
public Date getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
* @param updatedAt 更新时间
|
||||
*/
|
||||
public void setUpdatedAt(Date updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
* @return updated_by 更新人
|
||||
*/
|
||||
public String getUpdatedBy() {
|
||||
return updatedBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
* @param updatedBy 更新人
|
||||
*/
|
||||
public void setUpdatedBy(String updatedBy) {
|
||||
this.updatedBy = updatedBy == null ? null : updatedBy.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域管理员
|
||||
* @return admin 主题域管理员
|
||||
*/
|
||||
public String getAdmin() {
|
||||
return admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域管理员
|
||||
* @param admin 主题域管理员
|
||||
*/
|
||||
public void setAdmin(String admin) {
|
||||
this.admin = admin == null ? null : admin.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域管理员组织
|
||||
* @return admin_org 主题域管理员组织
|
||||
*/
|
||||
public String getAdminOrg() {
|
||||
return adminOrg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域管理员组织
|
||||
* @param adminOrg 主题域管理员组织
|
||||
*/
|
||||
public void setAdminOrg(String adminOrg) {
|
||||
this.adminOrg = adminOrg == null ? null : adminOrg.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域是否公开
|
||||
* @return is_open 主题域是否公开
|
||||
*/
|
||||
public Integer getIsOpen() {
|
||||
return isOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域是否公开
|
||||
* @param isOpen 主题域是否公开
|
||||
*/
|
||||
public void setIsOpen(Integer isOpen) {
|
||||
this.isOpen = isOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域可用用户
|
||||
* @return viewer 主题域可用用户
|
||||
*/
|
||||
public String getViewer() {
|
||||
return viewer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域可用用户
|
||||
* @param viewer 主题域可用用户
|
||||
*/
|
||||
public void setViewer(String viewer) {
|
||||
this.viewer = viewer == null ? null : viewer.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域可用组织
|
||||
* @return view_org 主题域可用组织
|
||||
*/
|
||||
public String getViewOrg() {
|
||||
return viewOrg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题域可用组织
|
||||
* @param viewOrg 主题域可用组织
|
||||
*/
|
||||
public void setViewOrg(String viewOrg) {
|
||||
this.viewOrg = viewOrg == null ? null : viewOrg.trim();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,383 +1,56 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.dataobject;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("s2_model")
|
||||
public class ModelDO {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String bizName;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Long domainId;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String alias;
|
||||
private String name;
|
||||
|
||||
private String bizName;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String viewer;
|
||||
private Long databaseId;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String viewOrg;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String admin;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String adminOrg;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Integer isOpen;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String createdBy;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Date createdAt;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String updatedBy;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Date updatedAt;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String drillDownDimensions;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String entity;
|
||||
private Date createdAt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return id
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
private String createdBy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
private Date updatedAt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
private String updatedBy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name == null ? null : name.trim();
|
||||
}
|
||||
private String modelDetail;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return biz_name
|
||||
*/
|
||||
public String getBizName() {
|
||||
return bizName;
|
||||
}
|
||||
private String depends;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bizName
|
||||
*/
|
||||
public void setBizName(String bizName) {
|
||||
this.bizName = bizName == null ? null : bizName.trim();
|
||||
}
|
||||
private String filterSql;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return domain_id
|
||||
*/
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
private String viewer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param domainId
|
||||
*/
|
||||
public void setDomainId(Long domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
private String viewOrg;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return alias
|
||||
*/
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
private String admin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param alias
|
||||
*/
|
||||
public void setAlias(String alias) {
|
||||
this.alias = alias == null ? null : alias.trim();
|
||||
}
|
||||
private String adminOrg;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return description
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
private Integer isOpen;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param description
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description == null ? null : description.trim();
|
||||
}
|
||||
private String drillDownDimensions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return viewer
|
||||
*/
|
||||
public String getViewer() {
|
||||
return viewer;
|
||||
}
|
||||
private String alias;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param viewer
|
||||
*/
|
||||
public void setViewer(String viewer) {
|
||||
this.viewer = viewer == null ? null : viewer.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return view_org
|
||||
*/
|
||||
public String getViewOrg() {
|
||||
return viewOrg;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param viewOrg
|
||||
*/
|
||||
public void setViewOrg(String viewOrg) {
|
||||
this.viewOrg = viewOrg == null ? null : viewOrg.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return admin
|
||||
*/
|
||||
public String getAdmin() {
|
||||
return admin;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param admin
|
||||
*/
|
||||
public void setAdmin(String admin) {
|
||||
this.admin = admin == null ? null : admin.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return admin_org
|
||||
*/
|
||||
public String getAdminOrg() {
|
||||
return adminOrg;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param adminOrg
|
||||
*/
|
||||
public void setAdminOrg(String adminOrg) {
|
||||
this.adminOrg = adminOrg == null ? null : adminOrg.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return is_open
|
||||
*/
|
||||
public Integer getIsOpen() {
|
||||
return isOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param isOpen
|
||||
*/
|
||||
public void setIsOpen(Integer isOpen) {
|
||||
this.isOpen = isOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return created_by
|
||||
*/
|
||||
public String getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param createdBy
|
||||
*/
|
||||
public void setCreatedBy(String createdBy) {
|
||||
this.createdBy = createdBy == null ? null : createdBy.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return created_at
|
||||
*/
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param createdAt
|
||||
*/
|
||||
public void setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return updated_by
|
||||
*/
|
||||
public String getUpdatedBy() {
|
||||
return updatedBy;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param updatedBy
|
||||
*/
|
||||
public void setUpdatedBy(String updatedBy) {
|
||||
this.updatedBy = updatedBy == null ? null : updatedBy.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return updated_at
|
||||
*/
|
||||
public Date getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param updatedAt
|
||||
*/
|
||||
public void setUpdatedAt(Date updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return drill_down_dimensions
|
||||
*/
|
||||
public String getDrillDownDimensions() {
|
||||
return drillDownDimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param drillDownDimensions
|
||||
*/
|
||||
public void setDrillDownDimensions(String drillDownDimensions) {
|
||||
this.drillDownDimensions = drillDownDimensions == null ? null : drillDownDimensions.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return status
|
||||
*/
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param status
|
||||
*/
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return entity
|
||||
*/
|
||||
public String getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entity
|
||||
*/
|
||||
public void setEntity(String entity) {
|
||||
this.entity = entity == null ? null : entity.trim();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.dataobject;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@TableName("s2_model_rela")
|
||||
public class ModelRelaDO {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long domainId;
|
||||
|
||||
private Long fromModelId;
|
||||
|
||||
private Long toModelId;
|
||||
|
||||
private String joinType;
|
||||
|
||||
private String joinCondition;
|
||||
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.manager;
|
||||
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DatasourceDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ModelDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Dim;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DatasourceYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DataModelYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionTimeTypeParamsTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.IdentifyYamlTpl;
|
||||
@@ -27,27 +27,27 @@ import org.springframework.util.CollectionUtils;
|
||||
@Slf4j
|
||||
public class DatasourceYamlManager {
|
||||
|
||||
public static DatasourceYamlTpl convert2YamlObj(Datasource datasource, DatabaseResp databaseResp) {
|
||||
DatasourceDetail datasourceDetail = datasource.getDatasourceDetail();
|
||||
public static DataModelYamlTpl convert2YamlObj(Datasource datasource, DatabaseResp databaseResp) {
|
||||
ModelDetail datasourceDetail = datasource.getDatasourceDetail();
|
||||
EngineAdaptor engineAdaptor = EngineAdaptorFactory.getEngineAdaptor(databaseResp.getType());
|
||||
SysTimeDimensionBuilder.addSysTimeDimension(datasourceDetail.getDimensions(), engineAdaptor);
|
||||
addInterCntMetric(datasource.getBizName(), datasourceDetail);
|
||||
DatasourceYamlTpl datasourceYamlTpl = new DatasourceYamlTpl();
|
||||
BeanUtils.copyProperties(datasourceDetail, datasourceYamlTpl);
|
||||
datasourceYamlTpl.setIdentifiers(datasourceDetail.getIdentifiers().stream().map(DatasourceYamlManager::convert)
|
||||
DataModelYamlTpl dataModelYamlTpl = new DataModelYamlTpl();
|
||||
BeanUtils.copyProperties(datasourceDetail, dataModelYamlTpl);
|
||||
dataModelYamlTpl.setIdentifiers(datasourceDetail.getIdentifiers().stream().map(DatasourceYamlManager::convert)
|
||||
.collect(Collectors.toList()));
|
||||
datasourceYamlTpl.setDimensions(datasourceDetail.getDimensions().stream().map(DatasourceYamlManager::convert)
|
||||
dataModelYamlTpl.setDimensions(datasourceDetail.getDimensions().stream().map(DatasourceYamlManager::convert)
|
||||
.collect(Collectors.toList()));
|
||||
datasourceYamlTpl.setMeasures(datasourceDetail.getMeasures().stream().map(DatasourceYamlManager::convert)
|
||||
dataModelYamlTpl.setMeasures(datasourceDetail.getMeasures().stream().map(DatasourceYamlManager::convert)
|
||||
.collect(Collectors.toList()));
|
||||
datasourceYamlTpl.setName(datasource.getBizName());
|
||||
datasourceYamlTpl.setSourceId(datasource.getDatabaseId());
|
||||
dataModelYamlTpl.setName(datasource.getBizName());
|
||||
dataModelYamlTpl.setSourceId(datasource.getDatabaseId());
|
||||
if (datasourceDetail.getQueryType().equalsIgnoreCase(DatasourceQueryEnum.SQL_QUERY.getName())) {
|
||||
datasourceYamlTpl.setSqlQuery(datasourceDetail.getSqlQuery());
|
||||
dataModelYamlTpl.setSqlQuery(datasourceDetail.getSqlQuery());
|
||||
} else {
|
||||
datasourceYamlTpl.setTableQuery(datasourceDetail.getTableQuery());
|
||||
dataModelYamlTpl.setTableQuery(datasourceDetail.getTableQuery());
|
||||
}
|
||||
return datasourceYamlTpl;
|
||||
return dataModelYamlTpl;
|
||||
}
|
||||
|
||||
public static DimensionYamlTpl convert(Dim dim) {
|
||||
@@ -81,7 +81,7 @@ public class DatasourceYamlManager {
|
||||
}
|
||||
|
||||
|
||||
private static void addInterCntMetric(String datasourceEnName, DatasourceDetail datasourceDetail) {
|
||||
private static void addInterCntMetric(String datasourceEnName, ModelDetail datasourceDetail) {
|
||||
Measure measure = new Measure();
|
||||
measure.setExpr("1");
|
||||
if (!CollectionUtils.isEmpty(datasourceDetail.getIdentifiers())) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.pojo;
|
||||
|
||||
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DatasourceDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ModelDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -13,7 +13,7 @@ public class Datasource extends SchemaItem {
|
||||
|
||||
private Long databaseId;
|
||||
|
||||
private DatasourceDetail datasourceDetail;
|
||||
private ModelDetail datasourceDetail;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -27,8 +27,6 @@ public class MetaFilter {
|
||||
|
||||
private List<Long> ids;
|
||||
|
||||
private Long datasourceId;
|
||||
|
||||
public MetaFilter(List<Long> modelIds) {
|
||||
this.modelIds = modelIds;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.pojo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ModelFilter extends MetaFilter {
|
||||
|
||||
private Long databaseId;
|
||||
|
||||
private List<Long> domainIds;
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.repository;
|
||||
|
||||
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DatasourceDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface DatasourceRepository {
|
||||
|
||||
void createDatasource(DatasourceDO datasourceDO);
|
||||
|
||||
void updateDatasource(DatasourceDO datasourceDO);
|
||||
|
||||
List<DatasourceDO> getDatasourceList();
|
||||
|
||||
List<DatasourceDO> getDatasourceList(Long modelId);
|
||||
|
||||
List<DatasourceDO> getDatasourceByDatabase(Long databaseId);
|
||||
|
||||
DatasourceDO getDatasourceById(Long id);
|
||||
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.repository;
|
||||
|
||||
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.ModelFilter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ModelRepository {
|
||||
@@ -9,10 +12,9 @@ public interface ModelRepository {
|
||||
|
||||
void updateModel(ModelDO modelDO);
|
||||
|
||||
void deleteModel(Long id);
|
||||
|
||||
List<ModelDO> getModelList();
|
||||
List<ModelDO> getModelList(ModelFilter modelFilter);
|
||||
|
||||
ModelDO getModelById(Long id);
|
||||
|
||||
void batchUpdate(List<ModelDO> modelDOS);
|
||||
}
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.MetricTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DatasourceDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Dim;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.MetricTypeParams;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DatasourceReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DimensionReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DatasourceDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.Datasource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class DatasourceConverter {
|
||||
|
||||
|
||||
public static DatasourceDO convert(DatasourceReq datasourceReq, User user) {
|
||||
DatasourceDO datasource = new DatasourceDO();
|
||||
DatasourceDetail datasourceDetail = getDatasourceDetail(datasourceReq);
|
||||
datasourceReq.createdBy(user.getName());
|
||||
BeanMapper.mapper(datasourceReq, datasource);
|
||||
datasource.setStatus(StatusEnum.ONLINE.getCode());
|
||||
datasource.setDatasourceDetail(JSONObject.toJSONString(datasourceDetail));
|
||||
return datasource;
|
||||
}
|
||||
|
||||
|
||||
public static DatasourceDO convert(DatasourceDO datasourceDO, DatasourceReq datasourceReq, User user) {
|
||||
DatasourceDetail datasourceDetail = getDatasourceDetail(datasourceReq);
|
||||
BeanMapper.mapper(datasourceReq, datasourceDO);
|
||||
datasourceDO.setDatasourceDetail(JSONObject.toJSONString((datasourceDetail)));
|
||||
datasourceDO.setUpdatedBy(user.getName());
|
||||
datasourceDO.setUpdatedAt(new Date());
|
||||
return datasourceDO;
|
||||
}
|
||||
|
||||
public static DatasourceResp convert(DatasourceDO datasourceDO) {
|
||||
DatasourceResp datasourceResp = new DatasourceResp();
|
||||
BeanUtils.copyProperties(datasourceDO, datasourceResp);
|
||||
datasourceResp.setDatasourceDetail(
|
||||
JSONObject.parseObject(datasourceDO.getDatasourceDetail(), DatasourceDetail.class));
|
||||
return datasourceResp;
|
||||
}
|
||||
|
||||
public static MeasureResp convert(Measure measure, DatasourceResp datasourceResp) {
|
||||
MeasureResp measureResp = new MeasureResp();
|
||||
BeanUtils.copyProperties(measure, measureResp);
|
||||
measureResp.setDatasourceId(datasourceResp.getId());
|
||||
measureResp.setDatasourceName(datasourceResp.getName());
|
||||
measureResp.setDatasourceBizName(datasourceResp.getBizName());
|
||||
measureResp.setModelId(datasourceResp.getModelId());
|
||||
return measureResp;
|
||||
}
|
||||
|
||||
public static DimensionReq convert(Dim dim, DatasourceDO datasourceDO) {
|
||||
DimensionReq dimensionReq = new DimensionReq();
|
||||
dimensionReq.setName(dim.getName());
|
||||
dimensionReq.setBizName(dim.getBizName());
|
||||
dimensionReq.setDescription(dim.getName());
|
||||
dimensionReq.setSemanticType("CATEGORY");
|
||||
dimensionReq.setDatasourceId(datasourceDO.getId());
|
||||
dimensionReq.setModelId(datasourceDO.getModelId());
|
||||
dimensionReq.setExpr(dim.getBizName());
|
||||
dimensionReq.setType("categorical");
|
||||
dimensionReq.setDescription(Objects.isNull(dim.getDescription()) ? "" : dim.getDescription());
|
||||
dimensionReq.setIsTag(dim.getIsTag());
|
||||
return dimensionReq;
|
||||
}
|
||||
|
||||
public static MetricReq convert(Measure measure, DatasourceDO datasourceDO) {
|
||||
measure.setDatasourceId(datasourceDO.getId());
|
||||
MetricReq metricReq = new MetricReq();
|
||||
metricReq.setName(measure.getName());
|
||||
metricReq.setBizName(measure.getBizName().replaceFirst(datasourceDO.getBizName() + "_", ""));
|
||||
metricReq.setDescription(measure.getName());
|
||||
metricReq.setModelId(datasourceDO.getModelId());
|
||||
metricReq.setMetricType(MetricTypeEnum.ATOMIC);
|
||||
MetricTypeParams exprTypeParams = new MetricTypeParams();
|
||||
exprTypeParams.setExpr(measure.getBizName());
|
||||
exprTypeParams.setMeasures(Lists.newArrayList(measure));
|
||||
metricReq.setTypeParams(exprTypeParams);
|
||||
return metricReq;
|
||||
}
|
||||
|
||||
public static DimensionReq convert(Identify identify, DatasourceDO datasourceDO) {
|
||||
DimensionReq dimensionReq = new DimensionReq();
|
||||
dimensionReq.setName(identify.getName());
|
||||
dimensionReq.setBizName(identify.getBizName());
|
||||
dimensionReq.setDescription(identify.getName());
|
||||
dimensionReq.setSemanticType("CATEGORY");
|
||||
dimensionReq.setDatasourceId(datasourceDO.getId());
|
||||
dimensionReq.setModelId(datasourceDO.getModelId());
|
||||
dimensionReq.setExpr(identify.getBizName());
|
||||
dimensionReq.setType(identify.getType());
|
||||
return dimensionReq;
|
||||
}
|
||||
|
||||
public static List<DatasourceResp> convertList(List<DatasourceDO> datasourceDOS) {
|
||||
List<DatasourceResp> datasourceDescs = Lists.newArrayList();
|
||||
if (!CollectionUtils.isEmpty(datasourceDOS)) {
|
||||
datasourceDescs = datasourceDOS.stream().map(DatasourceConverter::convert).collect(Collectors.toList());
|
||||
}
|
||||
return datasourceDescs;
|
||||
}
|
||||
|
||||
|
||||
private static boolean isCreateDimension(Dim dim) {
|
||||
return dim.getIsCreateDimension() == 1
|
||||
&& StringUtils.isNotBlank(dim.getName())
|
||||
&& !dim.getType().equalsIgnoreCase("time");
|
||||
}
|
||||
|
||||
private static boolean isCreateMetric(Measure measure) {
|
||||
return measure.getIsCreateMetric() == 1
|
||||
&& StringUtils.isNotBlank(measure.getName());
|
||||
}
|
||||
|
||||
public static List<Dim> getDimToCreateDimension(DatasourceDetail datasourceDetail) {
|
||||
return datasourceDetail.getDimensions().stream()
|
||||
.filter(DatasourceConverter::isCreateDimension)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<Measure> getMeasureToCreateMetric(DatasourceDetail datasourceDetail) {
|
||||
return datasourceDetail.getMeasures().stream()
|
||||
.filter(DatasourceConverter::isCreateMetric)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<DimensionReq> convertDimensionList(DatasourceDO datasourceDO) {
|
||||
List<DimensionReq> dimensionReqs = Lists.newArrayList();
|
||||
DatasourceDetail datasourceDetail = JSONObject.parseObject(datasourceDO.getDatasourceDetail(),
|
||||
DatasourceDetail.class);
|
||||
List<Dim> dims = getDimToCreateDimension(datasourceDetail);
|
||||
if (!CollectionUtils.isEmpty(dims)) {
|
||||
dimensionReqs = dims.stream().filter(dim -> StringUtils.isNotBlank(dim.getName()))
|
||||
.map(dim -> convert(dim, datasourceDO)).collect(Collectors.toList());
|
||||
}
|
||||
List<Identify> identifies = datasourceDetail.getIdentifiers();
|
||||
if (CollectionUtils.isEmpty(identifies)) {
|
||||
return dimensionReqs;
|
||||
}
|
||||
dimensionReqs.addAll(identifies.stream()
|
||||
.filter(i -> i.getType().equalsIgnoreCase("primary"))
|
||||
.filter(i -> StringUtils.isNotBlank(i.getName()))
|
||||
.map(identify -> convert(identify, datasourceDO)).collect(Collectors.toList()));
|
||||
return dimensionReqs;
|
||||
}
|
||||
|
||||
|
||||
public static List<MetricReq> convertMetricList(DatasourceDO datasourceDO) {
|
||||
DatasourceDetail datasourceDetail = JSONObject.parseObject(datasourceDO.getDatasourceDetail(),
|
||||
DatasourceDetail.class);
|
||||
List<Measure> measures = getMeasureToCreateMetric(datasourceDetail);
|
||||
if (CollectionUtils.isEmpty(measures)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
return measures.stream().map(measure -> convert(measure, datasourceDO)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static Datasource datasourceInfo2Datasource(DatasourceResp datasourceResp) {
|
||||
Datasource datasource = new Datasource();
|
||||
BeanUtils.copyProperties(datasourceResp, datasource);
|
||||
return datasource;
|
||||
}
|
||||
|
||||
private static DatasourceDetail getDatasourceDetail(DatasourceReq datasourceReq) {
|
||||
DatasourceDetail datasourceDetail = new DatasourceDetail();
|
||||
BeanMapper.mapper(datasourceReq, datasourceDetail);
|
||||
List<Measure> measures = datasourceDetail.getMeasures();
|
||||
for (Measure measure : measures) {
|
||||
if (StringUtils.isBlank(measure.getExpr())) {
|
||||
measure.setExpr(measure.getBizName());
|
||||
}
|
||||
if (StringUtils.isBlank(measure.getConstraint())) {
|
||||
measure.setConstraint(null);
|
||||
}
|
||||
if (StringUtils.isBlank(measure.getAlias())) {
|
||||
measure.setAlias(null);
|
||||
}
|
||||
measure.setBizName(String.format("%s_%s", datasourceReq.getBizName(), measure.getBizName()));
|
||||
}
|
||||
return datasourceDetail;
|
||||
}
|
||||
}
|
||||
@@ -3,25 +3,24 @@ package com.tencent.supersonic.semantic.model.domain.utils;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.tencent.supersonic.common.pojo.enums.DataTypeEnums;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DimValueMap;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DimensionReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DimensionDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.Dimension;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
public class DimensionConverter {
|
||||
|
||||
public static DimensionDO convert(DimensionDO dimensionDO, DimensionReq dimensionReq) {
|
||||
@@ -57,22 +56,18 @@ public class DimensionConverter {
|
||||
}
|
||||
|
||||
public static DimensionResp convert2DimensionResp(DimensionDO dimensionDO,
|
||||
Map<Long, String> fullPathMap,
|
||||
Map<Long, DatasourceResp> datasourceRespMap) {
|
||||
Map<Long, ModelResp> modelRespMap) {
|
||||
DimensionResp dimensionResp = new DimensionResp();
|
||||
BeanUtils.copyProperties(dimensionDO, dimensionResp);
|
||||
dimensionResp.setFullPath(fullPathMap.get(dimensionDO.getModelId()) + "/" + dimensionDO.getBizName());
|
||||
dimensionResp.setDatasourceId(
|
||||
datasourceRespMap.getOrDefault(dimensionResp.getDatasourceId(), new DatasourceResp()).getId());
|
||||
dimensionResp.setDatasourceName(
|
||||
datasourceRespMap.getOrDefault(dimensionResp.getDatasourceId(), new DatasourceResp()).getName());
|
||||
dimensionResp.setDatasourceBizName(
|
||||
datasourceRespMap.getOrDefault(dimensionResp.getDatasourceId(), new DatasourceResp()).getBizName());
|
||||
dimensionResp.setModelName(
|
||||
modelRespMap.getOrDefault(dimensionResp.getModelId(), new ModelResp()).getName());
|
||||
dimensionResp.setModelBizName(
|
||||
modelRespMap.getOrDefault(dimensionResp.getModelId(), new ModelResp()).getBizName());
|
||||
if (dimensionDO.getDefaultValues() != null) {
|
||||
dimensionResp.setDefaultValues(JSONObject.parseObject(dimensionDO.getDefaultValues(), List.class));
|
||||
}
|
||||
dimensionResp.setDatasourceFilterSql(
|
||||
datasourceRespMap.getOrDefault(dimensionResp.getDatasourceId(), new DatasourceResp()).getFilterSql());
|
||||
dimensionResp.setModelFilterSql(
|
||||
modelRespMap.getOrDefault(dimensionResp.getModelId(), new ModelResp()).getFilterSql());
|
||||
if (Strings.isNotEmpty(dimensionDO.getDimValueMaps())) {
|
||||
dimensionResp.setDimValueMaps(JsonUtil.toList(dimensionDO.getDimValueMaps(), DimValueMap.class));
|
||||
}
|
||||
|
||||
@@ -6,39 +6,25 @@ import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DomainReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DomainDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.Domain;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DomainConvert {
|
||||
|
||||
public static Domain convert(DomainReq domainReq) {
|
||||
Domain domain = new Domain();
|
||||
BeanUtils.copyProperties(domainReq, domain);
|
||||
domain.setStatus(StatusEnum.ONLINE.getCode());
|
||||
return domain;
|
||||
}
|
||||
|
||||
public static DomainDO convert(Domain domain, User user) {
|
||||
public static DomainDO convert(DomainReq domainReq, User user) {
|
||||
DomainDO domainDO = new DomainDO();
|
||||
BeanUtils.copyProperties(domain, domainDO);
|
||||
domainDO.setCreatedBy(user.getName());
|
||||
domainDO.setUpdatedBy(user.getName());
|
||||
domainDO.setCreatedAt(new Date());
|
||||
domainDO.setUpdatedAt(new Date());
|
||||
domainDO.setAdmin(String.join(",", domain.getAdmins()));
|
||||
domainDO.setAdminOrg(String.join(",", domain.getAdminOrgs()));
|
||||
domainDO.setViewer(String.join(",", domain.getViewers()));
|
||||
domainDO.setViewOrg(String.join(",", domain.getViewOrgs()));
|
||||
domainReq.createdBy(user.getName());
|
||||
BeanUtils.copyProperties(domainReq, domainDO);
|
||||
domainDO.setAdmin(String.join(",", domainReq.getAdmins()));
|
||||
domainDO.setAdminOrg(String.join(",", domainReq.getAdminOrgs()));
|
||||
domainDO.setViewer(String.join(",", domainReq.getViewers()));
|
||||
domainDO.setViewOrg(String.join(",", domainReq.getViewOrgs()));
|
||||
return domainDO;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,25 +4,25 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.common.pojo.DataFormat;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.MetricTypeParams;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.RelateDimension;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.MeasureYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.MetricTypeParamsYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.MetricYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.MetricDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.Metric;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
public class MetricConverter {
|
||||
|
||||
public static MetricDO convert2MetricDO(MetricReq metricReq) {
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.utils;
|
||||
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Entity;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
public class ModelConvert {
|
||||
|
||||
public static ModelDO convert(ModelReq modelReq) {
|
||||
ModelDO modelDO = new ModelDO();
|
||||
BeanMapper.mapper(modelReq, modelDO);
|
||||
modelDO.setEntity(JsonUtil.toString(modelReq.getEntity()));
|
||||
modelDO.setDrillDownDimensions(JsonUtil.toString(modelReq.getDrillDownDimensions()));
|
||||
modelDO.setStatus(StatusEnum.ONLINE.getCode());
|
||||
return modelDO;
|
||||
}
|
||||
|
||||
public static ModelResp convert(ModelDO modelDO) {
|
||||
ModelResp modelResp = new ModelResp();
|
||||
BeanUtils.copyProperties(modelDO, modelResp);
|
||||
modelResp.setAdmins(StringUtils.isBlank(modelDO.getAdmin())
|
||||
? Lists.newArrayList() : Arrays.asList(modelDO.getAdmin().split(",")));
|
||||
modelResp.setAdminOrgs(StringUtils.isBlank(modelDO.getAdminOrg())
|
||||
? Lists.newArrayList() : Arrays.asList(modelDO.getAdminOrg().split(",")));
|
||||
modelResp.setViewers(StringUtils.isBlank(modelDO.getViewer())
|
||||
? Lists.newArrayList() : Arrays.asList(modelDO.getViewer().split(",")));
|
||||
modelResp.setViewOrgs(StringUtils.isBlank(modelDO.getViewOrg())
|
||||
? Lists.newArrayList() : Arrays.asList(modelDO.getViewOrg().split(",")));
|
||||
modelResp.setEntity(JsonUtil.toObject(modelDO.getEntity(), Entity.class));
|
||||
modelResp.setDrillDownDimensions(JsonUtil.toList(modelDO.getDrillDownDimensions(), DrillDownDimension.class));
|
||||
return modelResp;
|
||||
}
|
||||
|
||||
public static ModelResp convert(ModelDO modelDO,
|
||||
Map<Long, DomainResp> domainRespMap) {
|
||||
ModelResp modelResp = convert(modelDO);
|
||||
DomainResp domainResp = domainRespMap.get(modelResp.getDomainId());
|
||||
if (domainResp != null) {
|
||||
String fullBizNamePath = domainResp.getFullPath() + modelResp.getBizName();
|
||||
modelResp.setFullPath(fullBizNamePath);
|
||||
}
|
||||
return modelResp;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
package com.tencent.supersonic.semantic.model.domain.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.common.util.BeanMapper;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.MetricTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Dim;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DrillDownDimension;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.MetricTypeParams;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ModelDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DimensionReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class ModelConverter {
|
||||
|
||||
|
||||
public static ModelDO convert(ModelReq modelReq, User user) {
|
||||
ModelDO modelDO = new ModelDO();
|
||||
ModelDetail modelDetail = getModelDetail(modelReq);
|
||||
modelReq.createdBy(user.getName());
|
||||
BeanMapper.mapper(modelReq, modelDO);
|
||||
modelDO.setStatus(StatusEnum.ONLINE.getCode());
|
||||
modelDO.setModelDetail(JSONObject.toJSONString(modelDetail));
|
||||
modelDO.setDrillDownDimensions(JSONObject.toJSONString(modelReq.getDrillDownDimensions()));
|
||||
return modelDO;
|
||||
}
|
||||
|
||||
public static ModelResp convert(ModelDO modelDO) {
|
||||
ModelResp modelResp = new ModelResp();
|
||||
BeanUtils.copyProperties(modelDO, modelResp);
|
||||
modelResp.setAdmins(StringUtils.isBlank(modelDO.getAdmin())
|
||||
? Lists.newArrayList() : Arrays.asList(modelDO.getAdmin().split(",")));
|
||||
modelResp.setAdminOrgs(StringUtils.isBlank(modelDO.getAdminOrg())
|
||||
? Lists.newArrayList() : Arrays.asList(modelDO.getAdminOrg().split(",")));
|
||||
modelResp.setViewers(StringUtils.isBlank(modelDO.getViewer())
|
||||
? Lists.newArrayList() : Arrays.asList(modelDO.getViewer().split(",")));
|
||||
modelResp.setViewOrgs(StringUtils.isBlank(modelDO.getViewOrg())
|
||||
? Lists.newArrayList() : Arrays.asList(modelDO.getViewOrg().split(",")));
|
||||
modelResp.setDrillDownDimensions(JsonUtil.toList(modelDO.getDrillDownDimensions(), DrillDownDimension.class));
|
||||
modelResp.setModelDetail(JSONObject.parseObject(modelDO.getModelDetail(), ModelDetail.class));
|
||||
return modelResp;
|
||||
}
|
||||
|
||||
public static ModelResp convert(ModelDO modelDO, Map<Long, DomainResp> domainRespMap) {
|
||||
ModelResp modelResp = convert(modelDO);
|
||||
DomainResp domainResp = domainRespMap.get(modelResp.getDomainId());
|
||||
if (domainResp != null) {
|
||||
String fullBizNamePath = domainResp.getFullPath() + modelResp.getBizName();
|
||||
modelResp.setFullPath(fullBizNamePath);
|
||||
}
|
||||
return modelResp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static ModelDO convert(ModelDO modelDO, ModelReq modelReq, User user) {
|
||||
ModelDetail modelDetail = getModelDetail(modelReq);
|
||||
BeanMapper.mapper(modelReq, modelDO);
|
||||
modelDO.setModelDetail(JSONObject.toJSONString((modelDetail)));
|
||||
modelDO.setUpdatedBy(user.getName());
|
||||
modelDO.setUpdatedAt(new Date());
|
||||
return modelDO;
|
||||
}
|
||||
|
||||
public static MeasureResp convert(Measure measure, ModelResp modelResp) {
|
||||
MeasureResp measureResp = new MeasureResp();
|
||||
BeanUtils.copyProperties(measure, measureResp);
|
||||
measureResp.setDatasourceId(modelResp.getId());
|
||||
measureResp.setDatasourceName(modelResp.getName());
|
||||
measureResp.setDatasourceBizName(modelResp.getBizName());
|
||||
measureResp.setModelId(modelResp.getId());
|
||||
return measureResp;
|
||||
}
|
||||
|
||||
public static DimensionReq convert(Dim dim, ModelDO modelDO) {
|
||||
DimensionReq dimensionReq = new DimensionReq();
|
||||
dimensionReq.setName(dim.getName());
|
||||
dimensionReq.setBizName(dim.getBizName());
|
||||
dimensionReq.setDescription(dim.getName());
|
||||
dimensionReq.setSemanticType("CATEGORY");
|
||||
dimensionReq.setModelId(modelDO.getId());
|
||||
dimensionReq.setExpr(dim.getBizName());
|
||||
dimensionReq.setType("categorical");
|
||||
dimensionReq.setDescription(Objects.isNull(dim.getDescription()) ? "" : dim.getDescription());
|
||||
dimensionReq.setIsTag(dim.getIsTag());
|
||||
return dimensionReq;
|
||||
}
|
||||
|
||||
public static MetricReq convert(Measure measure, ModelDO modelDO) {
|
||||
measure.setDatasourceId(modelDO.getId());
|
||||
MetricReq metricReq = new MetricReq();
|
||||
metricReq.setName(measure.getName());
|
||||
metricReq.setBizName(measure.getBizName().replaceFirst(modelDO.getBizName() + "_", ""));
|
||||
metricReq.setDescription(measure.getName());
|
||||
metricReq.setModelId(modelDO.getId());
|
||||
metricReq.setMetricType(MetricTypeEnum.ATOMIC);
|
||||
MetricTypeParams exprTypeParams = new MetricTypeParams();
|
||||
exprTypeParams.setExpr(measure.getBizName());
|
||||
exprTypeParams.setMeasures(Lists.newArrayList(measure));
|
||||
metricReq.setTypeParams(exprTypeParams);
|
||||
return metricReq;
|
||||
}
|
||||
|
||||
public static DimensionReq convert(Identify identify, ModelDO modelDO) {
|
||||
DimensionReq dimensionReq = new DimensionReq();
|
||||
dimensionReq.setName(identify.getName());
|
||||
dimensionReq.setBizName(identify.getBizName());
|
||||
dimensionReq.setDescription(identify.getName());
|
||||
dimensionReq.setSemanticType("CATEGORY");
|
||||
dimensionReq.setModelId(modelDO.getId());
|
||||
dimensionReq.setExpr(identify.getBizName());
|
||||
dimensionReq.setType(identify.getType());
|
||||
return dimensionReq;
|
||||
}
|
||||
|
||||
public static List<ModelResp> convertList(List<ModelDO> modelDOS) {
|
||||
List<ModelResp> modelDescs = Lists.newArrayList();
|
||||
if (!CollectionUtils.isEmpty(modelDOS)) {
|
||||
modelDescs = modelDOS.stream().map(ModelConverter::convert).collect(Collectors.toList());
|
||||
}
|
||||
return modelDescs;
|
||||
}
|
||||
|
||||
|
||||
private static boolean isCreateDimension(Dim dim) {
|
||||
return dim.getIsCreateDimension() == 1
|
||||
&& StringUtils.isNotBlank(dim.getName())
|
||||
&& !dim.getType().equalsIgnoreCase("time");
|
||||
}
|
||||
|
||||
private static boolean isCreateMetric(Measure measure) {
|
||||
return measure.getIsCreateMetric() == 1
|
||||
&& StringUtils.isNotBlank(measure.getName());
|
||||
}
|
||||
|
||||
public static List<Dim> getDimToCreateDimension(ModelDetail modelDetail) {
|
||||
return modelDetail.getDimensions().stream()
|
||||
.filter(ModelConverter::isCreateDimension)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<Measure> getMeasureToCreateMetric(ModelDetail modelDetail) {
|
||||
return modelDetail.getMeasures().stream()
|
||||
.filter(ModelConverter::isCreateMetric)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<DimensionReq> convertDimensionList(ModelDO modelDO) {
|
||||
List<DimensionReq> dimensionReqs = Lists.newArrayList();
|
||||
ModelDetail modelDetail = JSONObject.parseObject(modelDO.getModelDetail(),
|
||||
ModelDetail.class);
|
||||
List<Dim> dims = getDimToCreateDimension(modelDetail);
|
||||
if (!CollectionUtils.isEmpty(dims)) {
|
||||
dimensionReqs = dims.stream().filter(dim -> StringUtils.isNotBlank(dim.getName()))
|
||||
.map(dim -> convert(dim, modelDO)).collect(Collectors.toList());
|
||||
}
|
||||
List<Identify> identifies = modelDetail.getIdentifiers();
|
||||
if (CollectionUtils.isEmpty(identifies)) {
|
||||
return dimensionReqs;
|
||||
}
|
||||
dimensionReqs.addAll(identifies.stream()
|
||||
.filter(i -> i.getType().equalsIgnoreCase("primary"))
|
||||
.filter(i -> StringUtils.isNotBlank(i.getName()))
|
||||
.map(identify -> convert(identify, modelDO)).collect(Collectors.toList()));
|
||||
return dimensionReqs;
|
||||
}
|
||||
|
||||
|
||||
public static List<MetricReq> convertMetricList(ModelDO modelDO) {
|
||||
ModelDetail modelDetail = JSONObject.parseObject(modelDO.getModelDetail(),
|
||||
ModelDetail.class);
|
||||
List<Measure> measures = getMeasureToCreateMetric(modelDetail);
|
||||
if (CollectionUtils.isEmpty(measures)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
return measures.stream().map(measure -> convert(measure, modelDO)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static ModelDetail getModelDetail(ModelReq modelReq) {
|
||||
ModelDetail modelDetail = new ModelDetail();
|
||||
BeanMapper.mapper(modelReq.getModelDetail(), modelDetail);
|
||||
List<Measure> measures = modelDetail.getMeasures();
|
||||
for (Measure measure : measures) {
|
||||
if (StringUtils.isBlank(measure.getExpr())) {
|
||||
measure.setExpr(measure.getBizName());
|
||||
}
|
||||
if (StringUtils.isBlank(measure.getConstraint())) {
|
||||
measure.setConstraint(null);
|
||||
}
|
||||
if (StringUtils.isBlank(measure.getAlias())) {
|
||||
measure.setAlias(null);
|
||||
}
|
||||
measure.setBizName(String.format("%s_%s", modelReq.getBizName(), measure.getBizName()));
|
||||
}
|
||||
return modelDetail;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +1,10 @@
|
||||
package com.tencent.supersonic.semantic.model.infrastructure.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DomainDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DomainDOExample;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface DomainDOMapper {
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
long countByExample(DomainDOExample example);
|
||||
public interface DomainDOMapper extends BaseMapper<DomainDO> {
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int deleteByPrimaryKey(Long id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int insert(DomainDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int insertSelective(DomainDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
List<DomainDO> selectByExample(DomainDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
DomainDO selectByPrimaryKey(Long id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByPrimaryKeySelective(DomainDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByPrimaryKey(DomainDO record);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.tencent.supersonic.semantic.model.infrastructure.mapper;
|
||||
|
||||
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ModelDOCustomMapper {
|
||||
|
||||
void batchUpdateStatus(List<ModelDO> modelDOS);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,89 +1,11 @@
|
||||
package com.tencent.supersonic.semantic.model.infrastructure.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelDOExample;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@Mapper
|
||||
public interface ModelDOMapper {
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
long countByExample(ModelDOExample example);
|
||||
public interface ModelDOMapper extends BaseMapper<ModelDO> {
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int deleteByPrimaryKey(Long id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int insert(ModelDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int insertSelective(ModelDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
List<ModelDO> selectByExampleWithBLOBs(ModelDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
List<ModelDO> selectByExample(ModelDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
ModelDO selectByPrimaryKey(Long id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByExampleSelective(@Param("record") ModelDO record, @Param("example") ModelDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByExampleWithBLOBs(@Param("record") ModelDO record, @Param("example") ModelDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByExample(@Param("record") ModelDO record, @Param("example") ModelDOExample example);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByPrimaryKeySelective(ModelDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByPrimaryKeyWithBLOBs(ModelDO record);
|
||||
|
||||
/**
|
||||
*
|
||||
* @mbg.generated
|
||||
*/
|
||||
int updateByPrimaryKey(ModelDO record);
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.tencent.supersonic.semantic.model.infrastructure.mapper;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DatasourceDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelRelaDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface DatasourceDOMapper extends BaseMapper<DatasourceDO> {
|
||||
public interface ModelRelaDOMapper extends BaseMapper<ModelRelaDO> {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.model.infrastructure.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DatasourceDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DatasourceRepository;
|
||||
import com.tencent.supersonic.semantic.model.infrastructure.mapper.DatasourceDOMapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component
|
||||
public class DatasourceRepositoryImpl implements DatasourceRepository {
|
||||
|
||||
|
||||
private DatasourceDOMapper datasourceMapper;
|
||||
|
||||
public DatasourceRepositoryImpl(DatasourceDOMapper datasourceMapper) {
|
||||
this.datasourceMapper = datasourceMapper;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void createDatasource(DatasourceDO datasourceDO) {
|
||||
datasourceMapper.insert(datasourceDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDatasource(DatasourceDO datasourceDO) {
|
||||
datasourceMapper.updateById(datasourceDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasourceDO> getDatasourceList() {
|
||||
QueryWrapper<DatasourceDO> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().ne(DatasourceDO::getStatus, StatusEnum.DELETED.getCode());
|
||||
return datasourceMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasourceDO> getDatasourceList(Long modelId) {
|
||||
QueryWrapper<DatasourceDO> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().ne(DatasourceDO::getStatus, StatusEnum.DELETED.getCode())
|
||||
.eq(DatasourceDO::getModelId, modelId);
|
||||
return datasourceMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DatasourceDO> getDatasourceByDatabase(Long databaseId) {
|
||||
QueryWrapper<DatasourceDO> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().ne(DatasourceDO::getStatus, StatusEnum.DELETED.getCode())
|
||||
.eq(DatasourceDO::getDatabaseId, databaseId);
|
||||
return datasourceMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatasourceDO getDatasourceById(Long id) {
|
||||
return datasourceMapper.selectById(id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.tencent.supersonic.semantic.model.infrastructure.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DomainDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DomainDOExample;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DomainRepository;
|
||||
import com.tencent.supersonic.semantic.model.infrastructure.mapper.DomainDOMapper;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -27,23 +27,22 @@ public class DomainRepositoryImpl implements DomainRepository {
|
||||
|
||||
@Override
|
||||
public void updateDomain(DomainDO metaDomainDO) {
|
||||
domainDOMapper.updateByPrimaryKey(metaDomainDO);
|
||||
domainDOMapper.updateById(metaDomainDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDomain(Long id) {
|
||||
domainDOMapper.deleteByPrimaryKey(id);
|
||||
domainDOMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DomainDO> getDomainList() {
|
||||
DomainDOExample metaDomainDOExample = new DomainDOExample();
|
||||
return domainDOMapper.selectByExample(metaDomainDOExample);
|
||||
return domainDOMapper.selectList(Wrappers.emptyWrapper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainDO getDomainById(Long id) {
|
||||
return domainDOMapper.selectByPrimaryKey(id);
|
||||
return domainDOMapper.selectById(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,49 +1,67 @@
|
||||
package com.tencent.supersonic.semantic.model.infrastructure.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelDOExample;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.ModelFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.ModelRepository;
|
||||
import com.tencent.supersonic.semantic.model.infrastructure.mapper.ModelDOCustomMapper;
|
||||
import com.tencent.supersonic.semantic.model.infrastructure.mapper.ModelDOMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Component
|
||||
public class ModelRepositoryImpl implements ModelRepository {
|
||||
|
||||
|
||||
private ModelDOMapper modelDOMapper;
|
||||
|
||||
public ModelRepositoryImpl(ModelDOMapper modelDOMapper) {
|
||||
private ModelDOCustomMapper modelDOCustomMapper;
|
||||
|
||||
public ModelRepositoryImpl(ModelDOMapper modelDOMapper,
|
||||
ModelDOCustomMapper modelDOCustomMapper) {
|
||||
this.modelDOMapper = modelDOMapper;
|
||||
this.modelDOCustomMapper = modelDOCustomMapper;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void createModel(ModelDO datasourceDO) {
|
||||
modelDOMapper.insert(datasourceDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createModel(ModelDO modelDO) {
|
||||
modelDOMapper.insert(modelDO);
|
||||
public void updateModel(ModelDO datasourceDO) {
|
||||
modelDOMapper.updateById(datasourceDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateModel(ModelDO modelDO) {
|
||||
modelDOMapper.updateByPrimaryKeySelective(modelDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteModel(Long id) {
|
||||
ModelDO modelDO = modelDOMapper.selectByPrimaryKey(id);
|
||||
modelDO.setStatus(StatusEnum.DELETED.getCode());
|
||||
modelDOMapper.updateByPrimaryKey(modelDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModelDO> getModelList() {
|
||||
ModelDOExample modelDOExample = new ModelDOExample();
|
||||
modelDOExample.createCriteria().andStatusNotEqualTo(StatusEnum.DELETED.getCode());
|
||||
return modelDOMapper.selectByExampleWithBLOBs(modelDOExample);
|
||||
public List<ModelDO> getModelList(ModelFilter modelFilter) {
|
||||
QueryWrapper<ModelDO> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda().ne(ModelDO::getStatus, StatusEnum.DELETED.getCode());
|
||||
if (modelFilter.getDatabaseId() != null) {
|
||||
wrapper.lambda().eq(ModelDO::getDatabaseId, modelFilter.getDatabaseId());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(modelFilter.getDomainIds())) {
|
||||
wrapper.lambda().in(ModelDO::getDomainId, modelFilter.getDomainIds());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(modelFilter.getIds())) {
|
||||
wrapper.lambda().in(ModelDO::getId, modelFilter.getIds());
|
||||
}
|
||||
return modelDOMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelDO getModelById(Long id) {
|
||||
return modelDOMapper.selectByPrimaryKey(id);
|
||||
return modelDOMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchUpdate(List<ModelDO> modelDOS) {
|
||||
modelDOCustomMapper.batchUpdateStatus(modelDOS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.model.rest;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DatasourceReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MeasureResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/semantic/datasource")
|
||||
public class DatasourceController {
|
||||
|
||||
private DatasourceService datasourceService;
|
||||
|
||||
public DatasourceController(DatasourceService datasourceService) {
|
||||
this.datasourceService = datasourceService;
|
||||
}
|
||||
|
||||
@PostMapping("/createDatasource")
|
||||
public DatasourceResp createDatasource(@RequestBody DatasourceReq datasourceReq,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) throws Exception {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return datasourceService.createDatasource(datasourceReq, user);
|
||||
}
|
||||
|
||||
@PostMapping("/updateDatasource")
|
||||
public DatasourceResp updateDatasource(@RequestBody DatasourceReq datasourceReq,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) throws Exception {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return datasourceService.updateDatasource(datasourceReq, user);
|
||||
}
|
||||
|
||||
@GetMapping("/getDatasourceList/{modelId}")
|
||||
public List<DatasourceResp> getDatasourceList(@PathVariable("modelId") Long modelId) {
|
||||
return datasourceService.getDatasourceListNoMeasurePrefix(modelId);
|
||||
}
|
||||
|
||||
@GetMapping("/getMeasureListOfModel/{modelId}")
|
||||
public List<MeasureResp> getMeasureListOfModel(@PathVariable("modelId") Long modelId) {
|
||||
return datasourceService.getMeasureListOfModel(Lists.newArrayList(modelId));
|
||||
}
|
||||
|
||||
@DeleteMapping("deleteDatasource/{id}")
|
||||
public boolean deleteDatasource(@PathVariable("id") Long id,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
datasourceService.deleteDatasource(id, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,10 +3,12 @@ package com.tencent.supersonic.semantic.model.rest;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.semantic.api.model.request.MetaBatchReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.ModelFilter;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -33,8 +35,7 @@ public class ModelController {
|
||||
|
||||
@PostMapping("/createModel")
|
||||
public Boolean createModel(@RequestBody ModelReq modelReq,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
modelService.createModel(modelReq, user);
|
||||
return true;
|
||||
@@ -42,8 +43,7 @@ public class ModelController {
|
||||
|
||||
@PostMapping("/updateModel")
|
||||
public Boolean updateModel(@RequestBody ModelReq modelReq,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
modelService.updateModel(modelReq, user);
|
||||
return true;
|
||||
@@ -51,8 +51,7 @@ public class ModelController {
|
||||
|
||||
@DeleteMapping("/deleteModel/{modelId}")
|
||||
public Boolean deleteModel(@PathVariable("modelId") Long modelId,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
modelService.deleteModel(modelId, user);
|
||||
return true;
|
||||
@@ -60,8 +59,7 @@ public class ModelController {
|
||||
|
||||
@GetMapping("/getModelList/{domainId}")
|
||||
public List<ModelResp> getModelList(@PathVariable("domainId") Long domainId,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
return modelService.getModelListWithAuth(user, domainId, AuthType.ADMIN);
|
||||
}
|
||||
@@ -74,8 +72,10 @@ public class ModelController {
|
||||
|
||||
@GetMapping("/getModelListByIds/{modelIds}")
|
||||
public List<ModelResp> getModelListByIds(@PathVariable("modelIds") String modelIds) {
|
||||
return modelService.getModelList(Arrays.stream(modelIds.split(",")).map(Long::parseLong)
|
||||
.collect(Collectors.toList()));
|
||||
List<Long> ids = Arrays.stream(modelIds.split(",")).map(Long::parseLong).collect(Collectors.toList());
|
||||
ModelFilter modelFilter = new ModelFilter();
|
||||
modelFilter.setIds(ids);
|
||||
return modelService.getModelList(modelFilter);
|
||||
}
|
||||
|
||||
@GetMapping("/getModelDatabase/{modelId}")
|
||||
@@ -83,4 +83,14 @@ public class ModelController {
|
||||
return modelService.getDatabaseByModelId(modelId);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/batchUpdateStatus")
|
||||
public Boolean batchUpdateStatus(@RequestBody MetaBatchReq metaBatchReq,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
User user = UserHolder.findUser(request, response);
|
||||
modelService.batchUpdateStatus(metaBatchReq, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.tencent.supersonic.semantic.model.rest;
|
||||
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.ModelRela;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelRelaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/semantic/modelRela")
|
||||
public class ModelRelaController {
|
||||
|
||||
@Autowired
|
||||
private ModelRelaService modelRelaService;
|
||||
|
||||
@PostMapping
|
||||
public boolean save(@RequestBody ModelRela modelRela, User user) {
|
||||
modelRelaService.save(modelRela, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public boolean update(@RequestBody ModelRela modelRela, User user) {
|
||||
modelRelaService.update(modelRela, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
@RequestMapping("/list")
|
||||
public List<ModelRela> getModelRelaList(@RequestParam("domainId") Long domainId) {
|
||||
return modelRelaService.getModelRelaList(domainId);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public void delete(@PathVariable("id") Long id) {
|
||||
modelRelaService.delete(id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -5,12 +5,8 @@ import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ViewInfoReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaRelaResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ViewInfoDO;
|
||||
import com.tencent.supersonic.semantic.model.application.ViewInfoServiceImpl;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ViewInfoDO;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -19,6 +15,10 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/semantic/viewInfo")
|
||||
public class ViewInfoController {
|
||||
@@ -47,9 +47,9 @@ public class ViewInfoController {
|
||||
viewInfoServiceImpl.deleteViewInfo(id);
|
||||
}
|
||||
|
||||
@GetMapping("/getDomainSchemaRela/{modelId}")
|
||||
public List<ModelSchemaRelaResp> getDomainSchema(@PathVariable("modelId") Long modelId) {
|
||||
return viewInfoServiceImpl.getDomainSchema(modelId);
|
||||
@GetMapping("/getDomainSchemaRela/{domainId}")
|
||||
public List<ModelSchemaRelaResp> getDomainSchema(@PathVariable("domainId") Long domainId) {
|
||||
return viewInfoServiceImpl.getDomainSchema(domainId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,480 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.tencent.supersonic.semantic.model.infrastructure.mapper.ModelDOMapper">
|
||||
<resultMap id="BaseResultMap" type="com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO">
|
||||
<id column="id" jdbcType="BIGINT" property="id" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="biz_name" jdbcType="VARCHAR" property="bizName" />
|
||||
<result column="domain_id" jdbcType="BIGINT" property="domainId" />
|
||||
<result column="alias" jdbcType="VARCHAR" property="alias" />
|
||||
<result column="description" jdbcType="VARCHAR" property="description" />
|
||||
<result column="viewer" jdbcType="VARCHAR" property="viewer" />
|
||||
<result column="view_org" jdbcType="VARCHAR" property="viewOrg" />
|
||||
<result column="admin" jdbcType="VARCHAR" property="admin" />
|
||||
<result column="admin_org" jdbcType="VARCHAR" property="adminOrg" />
|
||||
<result column="is_open" jdbcType="INTEGER" property="isOpen" />
|
||||
<result column="created_by" jdbcType="VARCHAR" property="createdBy" />
|
||||
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
|
||||
<result column="updated_by" jdbcType="VARCHAR" property="updatedBy" />
|
||||
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
|
||||
<result column="drill_down_dimensions" jdbcType="VARCHAR" property="drillDownDimensions" />
|
||||
<result column="status" jdbcType="INTEGER" property="status" />
|
||||
</resultMap>
|
||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO">
|
||||
<result column="entity" jdbcType="LONGVARCHAR" property="entity" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="oredCriteria" item="criteria" separator="or">
|
||||
<if test="criteria.valid">
|
||||
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||
<foreach collection="criteria.criteria" item="criterion">
|
||||
<choose>
|
||||
<when test="criterion.noValue">
|
||||
and ${criterion.condition}
|
||||
</when>
|
||||
<when test="criterion.singleValue">
|
||||
and ${criterion.condition} #{criterion.value}
|
||||
</when>
|
||||
<when test="criterion.betweenValue">
|
||||
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||
</when>
|
||||
<when test="criterion.listValue">
|
||||
and ${criterion.condition}
|
||||
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||
#{listItem}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</foreach>
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Update_By_Example_Where_Clause">
|
||||
<where>
|
||||
<foreach collection="example.oredCriteria" item="criteria" separator="or">
|
||||
<if test="criteria.valid">
|
||||
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||
<foreach collection="criteria.criteria" item="criterion">
|
||||
<choose>
|
||||
<when test="criterion.noValue">
|
||||
and ${criterion.condition}
|
||||
</when>
|
||||
<when test="criterion.singleValue">
|
||||
and ${criterion.condition} #{criterion.value}
|
||||
</when>
|
||||
<when test="criterion.betweenValue">
|
||||
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
|
||||
</when>
|
||||
<when test="criterion.listValue">
|
||||
and ${criterion.condition}
|
||||
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||
#{listItem}
|
||||
</foreach>
|
||||
</when>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
</if>
|
||||
</foreach>
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, name, biz_name, domain_id, alias, description, viewer, view_org, admin, admin_org,
|
||||
is_open, created_by, created_at, updated_by, updated_at, drill_down_dimensions, status
|
||||
</sql>
|
||||
<sql id="Blob_Column_List">
|
||||
entity
|
||||
</sql>
|
||||
<select id="selectByExampleWithBLOBs" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.ModelDOExample" resultMap="ResultMapWithBLOBs">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
,
|
||||
<include refid="Blob_Column_List" />
|
||||
from s2_model
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
<if test="orderByClause != null">
|
||||
order by ${orderByClause}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectByExample" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.ModelDOExample" resultMap="BaseResultMap">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
from s2_model
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
<if test="orderByClause != null">
|
||||
order by ${orderByClause}
|
||||
</if>
|
||||
<if test="limitStart != null and limitStart>=0">
|
||||
limit #{limitStart} , #{limitEnd}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="ResultMapWithBLOBs">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
,
|
||||
<include refid="Blob_Column_List" />
|
||||
from s2_model
|
||||
where id = #{id,jdbcType=BIGINT}
|
||||
</select>
|
||||
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
|
||||
delete from s2_model
|
||||
where id = #{id,jdbcType=BIGINT}
|
||||
</delete>
|
||||
<insert id="insert" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO">
|
||||
insert into s2_model (id, name, biz_name,
|
||||
domain_id, alias, description,
|
||||
viewer, view_org, admin,
|
||||
admin_org, is_open, created_by,
|
||||
created_at, updated_by, updated_at,
|
||||
drill_down_dimensions, status, entity
|
||||
)
|
||||
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{bizName,jdbcType=VARCHAR},
|
||||
#{domainId,jdbcType=BIGINT}, #{alias,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR},
|
||||
#{viewer,jdbcType=VARCHAR}, #{viewOrg,jdbcType=VARCHAR}, #{admin,jdbcType=VARCHAR},
|
||||
#{adminOrg,jdbcType=VARCHAR}, #{isOpen,jdbcType=INTEGER}, #{createdBy,jdbcType=VARCHAR},
|
||||
#{createdAt,jdbcType=TIMESTAMP}, #{updatedBy,jdbcType=VARCHAR}, #{updatedAt,jdbcType=TIMESTAMP},
|
||||
#{drillDownDimensions,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER}, #{entity,jdbcType=LONGVARCHAR}
|
||||
)
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO">
|
||||
insert into s2_model
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
id,
|
||||
</if>
|
||||
<if test="name != null">
|
||||
name,
|
||||
</if>
|
||||
<if test="bizName != null">
|
||||
biz_name,
|
||||
</if>
|
||||
<if test="domainId != null">
|
||||
domain_id,
|
||||
</if>
|
||||
<if test="alias != null">
|
||||
alias,
|
||||
</if>
|
||||
<if test="description != null">
|
||||
description,
|
||||
</if>
|
||||
<if test="viewer != null">
|
||||
viewer,
|
||||
</if>
|
||||
<if test="viewOrg != null">
|
||||
view_org,
|
||||
</if>
|
||||
<if test="admin != null">
|
||||
admin,
|
||||
</if>
|
||||
<if test="adminOrg != null">
|
||||
admin_org,
|
||||
</if>
|
||||
<if test="isOpen != null">
|
||||
is_open,
|
||||
</if>
|
||||
<if test="createdBy != null">
|
||||
created_by,
|
||||
</if>
|
||||
<if test="createdAt != null">
|
||||
created_at,
|
||||
</if>
|
||||
<if test="updatedBy != null">
|
||||
updated_by,
|
||||
</if>
|
||||
<if test="updatedAt != null">
|
||||
updated_at,
|
||||
</if>
|
||||
<if test="drillDownDimensions != null">
|
||||
drill_down_dimensions,
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status,
|
||||
</if>
|
||||
<if test="entity != null">
|
||||
entity,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
#{id,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="name != null">
|
||||
#{name,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="bizName != null">
|
||||
#{bizName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="domainId != null">
|
||||
#{domainId,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="alias != null">
|
||||
#{alias,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="description != null">
|
||||
#{description,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="viewer != null">
|
||||
#{viewer,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="viewOrg != null">
|
||||
#{viewOrg,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="admin != null">
|
||||
#{admin,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="adminOrg != null">
|
||||
#{adminOrg,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="isOpen != null">
|
||||
#{isOpen,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="createdBy != null">
|
||||
#{createdBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createdAt != null">
|
||||
#{createdAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="updatedBy != null">
|
||||
#{updatedBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="updatedAt != null">
|
||||
#{updatedAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="drillDownDimensions != null">
|
||||
#{drillDownDimensions,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
#{status,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="entity != null">
|
||||
#{entity,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.ModelDOExample" resultType="java.lang.Long">
|
||||
select count(*) from s2_model
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</select>
|
||||
<update id="updateByExampleSelective" parameterType="map">
|
||||
update s2_model
|
||||
<set>
|
||||
<if test="record.id != null">
|
||||
id = #{record.id,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="record.name != null">
|
||||
name = #{record.name,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.bizName != null">
|
||||
biz_name = #{record.bizName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.domainId != null">
|
||||
domain_id = #{record.domainId,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="record.alias != null">
|
||||
alias = #{record.alias,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.description != null">
|
||||
description = #{record.description,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.viewer != null">
|
||||
viewer = #{record.viewer,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.viewOrg != null">
|
||||
view_org = #{record.viewOrg,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.admin != null">
|
||||
admin = #{record.admin,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.adminOrg != null">
|
||||
admin_org = #{record.adminOrg,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.isOpen != null">
|
||||
is_open = #{record.isOpen,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="record.createdBy != null">
|
||||
created_by = #{record.createdBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.createdAt != null">
|
||||
created_at = #{record.createdAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="record.updatedBy != null">
|
||||
updated_by = #{record.updatedBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.updatedAt != null">
|
||||
updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="record.drillDownDimensions != null">
|
||||
drill_down_dimensions = #{record.drillDownDimensions,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.status != null">
|
||||
status = #{record.status,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="record.entity != null">
|
||||
entity = #{record.entity,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExampleWithBLOBs" parameterType="map">
|
||||
update s2_model
|
||||
set id = #{record.id,jdbcType=BIGINT},
|
||||
name = #{record.name,jdbcType=VARCHAR},
|
||||
biz_name = #{record.bizName,jdbcType=VARCHAR},
|
||||
domain_id = #{record.domainId,jdbcType=BIGINT},
|
||||
alias = #{record.alias,jdbcType=VARCHAR},
|
||||
description = #{record.description,jdbcType=VARCHAR},
|
||||
viewer = #{record.viewer,jdbcType=VARCHAR},
|
||||
view_org = #{record.viewOrg,jdbcType=VARCHAR},
|
||||
admin = #{record.admin,jdbcType=VARCHAR},
|
||||
admin_org = #{record.adminOrg,jdbcType=VARCHAR},
|
||||
is_open = #{record.isOpen,jdbcType=INTEGER},
|
||||
created_by = #{record.createdBy,jdbcType=VARCHAR},
|
||||
created_at = #{record.createdAt,jdbcType=TIMESTAMP},
|
||||
updated_by = #{record.updatedBy,jdbcType=VARCHAR},
|
||||
updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
|
||||
drill_down_dimensions = #{record.drillDownDimensions,jdbcType=VARCHAR},
|
||||
status = #{record.status,jdbcType=INTEGER},
|
||||
entity = #{record.entity,jdbcType=LONGVARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update s2_model
|
||||
set id = #{record.id,jdbcType=BIGINT},
|
||||
name = #{record.name,jdbcType=VARCHAR},
|
||||
biz_name = #{record.bizName,jdbcType=VARCHAR},
|
||||
domain_id = #{record.domainId,jdbcType=BIGINT},
|
||||
alias = #{record.alias,jdbcType=VARCHAR},
|
||||
description = #{record.description,jdbcType=VARCHAR},
|
||||
viewer = #{record.viewer,jdbcType=VARCHAR},
|
||||
view_org = #{record.viewOrg,jdbcType=VARCHAR},
|
||||
admin = #{record.admin,jdbcType=VARCHAR},
|
||||
admin_org = #{record.adminOrg,jdbcType=VARCHAR},
|
||||
is_open = #{record.isOpen,jdbcType=INTEGER},
|
||||
created_by = #{record.createdBy,jdbcType=VARCHAR},
|
||||
created_at = #{record.createdAt,jdbcType=TIMESTAMP},
|
||||
updated_by = #{record.updatedBy,jdbcType=VARCHAR},
|
||||
updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
|
||||
drill_down_dimensions = #{record.drillDownDimensions,jdbcType=VARCHAR},
|
||||
status = #{record.status,jdbcType=INTEGER}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByPrimaryKeySelective" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO">
|
||||
update s2_model
|
||||
<set>
|
||||
<if test="name != null">
|
||||
name = #{name,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="bizName != null">
|
||||
biz_name = #{bizName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="domainId != null">
|
||||
domain_id = #{domainId,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="alias != null">
|
||||
alias = #{alias,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="description != null">
|
||||
description = #{description,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="viewer != null">
|
||||
viewer = #{viewer,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="viewOrg != null">
|
||||
view_org = #{viewOrg,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="admin != null">
|
||||
admin = #{admin,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="adminOrg != null">
|
||||
admin_org = #{adminOrg,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="isOpen != null">
|
||||
is_open = #{isOpen,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="createdBy != null">
|
||||
created_by = #{createdBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createdAt != null">
|
||||
created_at = #{createdAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="updatedBy != null">
|
||||
updated_by = #{updatedBy,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="updatedAt != null">
|
||||
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
|
||||
</if>
|
||||
<if test="drillDownDimensions != null">
|
||||
drill_down_dimensions = #{drillDownDimensions,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status = #{status,jdbcType=INTEGER},
|
||||
</if>
|
||||
<if test="entity != null">
|
||||
entity = #{entity,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=BIGINT}
|
||||
</update>
|
||||
<update id="updateByPrimaryKeyWithBLOBs" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO">
|
||||
update s2_model
|
||||
set name = #{name,jdbcType=VARCHAR},
|
||||
biz_name = #{bizName,jdbcType=VARCHAR},
|
||||
domain_id = #{domainId,jdbcType=BIGINT},
|
||||
alias = #{alias,jdbcType=VARCHAR},
|
||||
description = #{description,jdbcType=VARCHAR},
|
||||
viewer = #{viewer,jdbcType=VARCHAR},
|
||||
view_org = #{viewOrg,jdbcType=VARCHAR},
|
||||
admin = #{admin,jdbcType=VARCHAR},
|
||||
admin_org = #{adminOrg,jdbcType=VARCHAR},
|
||||
is_open = #{isOpen,jdbcType=INTEGER},
|
||||
created_by = #{createdBy,jdbcType=VARCHAR},
|
||||
created_at = #{createdAt,jdbcType=TIMESTAMP},
|
||||
updated_by = #{updatedBy,jdbcType=VARCHAR},
|
||||
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
|
||||
drill_down_dimensions = #{drillDownDimensions,jdbcType=VARCHAR},
|
||||
status = #{status,jdbcType=INTEGER},
|
||||
entity = #{entity,jdbcType=LONGVARCHAR}
|
||||
where id = #{id,jdbcType=BIGINT}
|
||||
</update>
|
||||
<update id="updateByPrimaryKey" parameterType="com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO">
|
||||
update s2_model
|
||||
set name = #{name,jdbcType=VARCHAR},
|
||||
biz_name = #{bizName,jdbcType=VARCHAR},
|
||||
domain_id = #{domainId,jdbcType=BIGINT},
|
||||
alias = #{alias,jdbcType=VARCHAR},
|
||||
description = #{description,jdbcType=VARCHAR},
|
||||
viewer = #{viewer,jdbcType=VARCHAR},
|
||||
view_org = #{viewOrg,jdbcType=VARCHAR},
|
||||
admin = #{admin,jdbcType=VARCHAR},
|
||||
admin_org = #{adminOrg,jdbcType=VARCHAR},
|
||||
is_open = #{isOpen,jdbcType=INTEGER},
|
||||
created_by = #{createdBy,jdbcType=VARCHAR},
|
||||
created_at = #{createdAt,jdbcType=TIMESTAMP},
|
||||
updated_by = #{updatedBy,jdbcType=VARCHAR},
|
||||
updated_at = #{updatedAt,jdbcType=TIMESTAMP},
|
||||
drill_down_dimensions = #{drillDownDimensions,jdbcType=VARCHAR},
|
||||
status = #{status,jdbcType=INTEGER}
|
||||
where id = #{id,jdbcType=BIGINT}
|
||||
</update>
|
||||
</mapper>
|
||||
@@ -5,7 +5,6 @@
|
||||
<resultMap id="BaseResultMap" type="com.tencent.supersonic.semantic.model.domain.dataobject.DimensionDO">
|
||||
<id column="id" jdbcType="BIGINT" property="id" />
|
||||
<result column="model_id" jdbcType="BIGINT" property="modelId" />
|
||||
<result column="datasource_id" jdbcType="BIGINT" property="datasourceId" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="biz_name" jdbcType="VARCHAR" property="bizName" />
|
||||
<result column="description" jdbcType="VARCHAR" property="description" />
|
||||
@@ -67,8 +66,7 @@
|
||||
<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into s2_dimension (name, biz_name,
|
||||
description, status, model_id,
|
||||
type, type_params, expr,
|
||||
datasource_id, created_at, created_by,
|
||||
type, type_params, expr,created_at, created_by,
|
||||
updated_by, updated_at, semantic_type,sensitive_level, is_tag)
|
||||
values
|
||||
<foreach collection="list" item="dimension" separator=",">
|
||||
@@ -76,8 +74,7 @@
|
||||
#{dimension.description,jdbcType=VARCHAR}, #{dimension.status,jdbcType=INTEGER},
|
||||
#{dimension.modelId,jdbcType=BIGINT},
|
||||
#{dimension.type,jdbcType=VARCHAR}, #{dimension.typeParams,jdbcType=VARCHAR},
|
||||
#{dimension.expr,jdbcType=VARCHAR},
|
||||
#{dimension.datasourceId,jdbcType=BIGINT}, #{dimension.createdAt,jdbcType=TIMESTAMP},
|
||||
#{dimension.expr,jdbcType=VARCHAR}, #{dimension.createdAt,jdbcType=TIMESTAMP},
|
||||
#{dimension.createdBy,jdbcType=VARCHAR},
|
||||
#{dimension.updatedBy,jdbcType=VARCHAR}, #{dimension.updatedAt,jdbcType=TIMESTAMP},
|
||||
#{dimension.semanticType,jdbcType=VARCHAR},
|
||||
@@ -161,9 +158,6 @@
|
||||
<if test="createdBy != null">
|
||||
and created_by = #{createdBy}
|
||||
</if>
|
||||
<if test="datasourceId != null">
|
||||
and datasource_id = #{datasourceId}
|
||||
</if>
|
||||
<if test="isTag != null and isTag == 1">
|
||||
and is_tag = 1
|
||||
</if>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.tencent.supersonic.semantic.model.infrastructure.mapper.ModelDOCustomMapper">
|
||||
|
||||
<update id="batchUpdateStatus" parameterType="java.util.List">
|
||||
<foreach collection="list" item="dimension" separator=";">
|
||||
update s2_model
|
||||
set
|
||||
status = #{model.status,jdbcType=INTEGER},
|
||||
updated_by = #{model.updatedBy,jdbcType=VARCHAR},
|
||||
updated_at = #{model.updatedAt,jdbcType=TIMESTAMP}
|
||||
where id = #{model.id,jdbcType=BIGINT}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
|
||||
</mapper>
|
||||
@@ -1,218 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.model.application;
|
||||
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.DimensionTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.IdentifyTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DatasourceDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Dim;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DimensionTimeTypeParams;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.request.DatasourceReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatabaseService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.DatasourceDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DatasourceRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DateInfoRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.DatasourceConverter;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class DatasourceServiceImplTest {
|
||||
|
||||
@Test
|
||||
void createDatasource() throws Exception {
|
||||
MetricService metricService = Mockito.mock(MetricService.class);
|
||||
DimensionService dimensionService = Mockito.mock(DimensionService.class);
|
||||
DatasourceRepository datasourceRepository = Mockito.mock(DatasourceRepository.class);
|
||||
DatabaseService databaseService = Mockito.mock(DatabaseService.class);
|
||||
DateInfoRepository dateInfoRepository = Mockito.mock(DateInfoRepository.class);
|
||||
DatasourceServiceImpl datasourceService = new DatasourceServiceImpl(datasourceRepository, databaseService,
|
||||
dimensionService, metricService, dateInfoRepository);
|
||||
DatasourceResp actualDatasourceResp = datasourceService.createDatasource(
|
||||
mockDatasourceReq(), User.getFakeUser());
|
||||
DatasourceResp expectedDatasourceResp = buildExpectedDatasourceResp();
|
||||
Assertions.assertEquals(expectedDatasourceResp, actualDatasourceResp);
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateDatasource() throws Exception {
|
||||
MetricService metricService = Mockito.mock(MetricService.class);
|
||||
DimensionService dimensionService = Mockito.mock(DimensionService.class);
|
||||
DatasourceRepository datasourceRepository = Mockito.mock(DatasourceRepository.class);
|
||||
DatabaseService databaseService = Mockito.mock(DatabaseService.class);
|
||||
DateInfoRepository dateInfoRepository = Mockito.mock(DateInfoRepository.class);
|
||||
DatasourceServiceImpl datasourceService = new DatasourceServiceImpl(datasourceRepository, databaseService,
|
||||
dimensionService, metricService, dateInfoRepository);
|
||||
DatasourceReq datasourceReq = mockDatasourceReq_update();
|
||||
DatasourceDO datasourceDO = DatasourceConverter.convert(mockDatasourceReq(), User.getFakeUser());
|
||||
when(datasourceRepository.getDatasourceById(datasourceReq.getId())).thenReturn(datasourceDO);
|
||||
User user = User.getFakeUser();
|
||||
user.setName("alice");
|
||||
DatasourceResp actualDatasourceResp = datasourceService.updateDatasource(mockDatasourceReq_update(), user);
|
||||
DatasourceResp expectedDatasourceResp = buildExpectedDatasourceResp_update();
|
||||
Assertions.assertEquals(expectedDatasourceResp, actualDatasourceResp);
|
||||
Assertions.assertEquals("admin", actualDatasourceResp.getCreatedBy());
|
||||
Assertions.assertEquals("alice", actualDatasourceResp.getUpdatedBy());
|
||||
}
|
||||
|
||||
|
||||
private DatasourceReq mockDatasourceReq() {
|
||||
DatasourceReq datasourceReq = new DatasourceReq();
|
||||
datasourceReq.setName("PVUV统计");
|
||||
datasourceReq.setBizName("s2_pv_uv_statis");
|
||||
datasourceReq.setDescription("PVUV统计");
|
||||
datasourceReq.setDatabaseId(1L);
|
||||
|
||||
List<Identify> identifiers = new ArrayList<>();
|
||||
identifiers.add(new Identify("用户名", IdentifyTypeEnum.primary.name(), "user_name"));
|
||||
datasourceReq.setIdentifiers(identifiers);
|
||||
|
||||
List<Dim> dimensions = new ArrayList<>();
|
||||
Dim dimension1 = new Dim("", "imp_date", DimensionTypeEnum.time.name(), 0);
|
||||
dimension1.setTypeParams(new DimensionTimeTypeParams());
|
||||
dimensions.add(dimension1);
|
||||
Dim dimension2 = new Dim("", "page", DimensionTypeEnum.categorical.name(), 0);
|
||||
dimension2.setExpr("page");
|
||||
dimensions.add(dimension2);
|
||||
datasourceReq.setDimensions(dimensions);
|
||||
|
||||
List<Measure> measures = new ArrayList<>();
|
||||
Measure measure1 = new Measure("访问次数", "pv", AggOperatorEnum.SUM.name(), 1);
|
||||
measures.add(measure1);
|
||||
|
||||
Measure measure2 = new Measure("访问人数", "uv", AggOperatorEnum.COUNT_DISTINCT.name(), 1);
|
||||
measures.add(measure2);
|
||||
|
||||
datasourceReq.setMeasures(measures);
|
||||
datasourceReq.setSqlQuery("SELECT imp_date, user_name, page, 1 as pv, user_name as uv FROM s2_pv_uv_statis");
|
||||
datasourceReq.setQueryType("sql_query");
|
||||
datasourceReq.setModelId(1L);
|
||||
datasourceReq.setFilterSql("where user_name = 'alice'");
|
||||
return datasourceReq;
|
||||
}
|
||||
|
||||
private DatasourceReq mockDatasourceReq_update() {
|
||||
DatasourceReq datasourceReq = new DatasourceReq();
|
||||
datasourceReq.setId(1L);
|
||||
datasourceReq.setName("PVUV统计_a");
|
||||
datasourceReq.setBizName("s2_pv_uv_statis_a");
|
||||
datasourceReq.setDescription("PVUV统计_a");
|
||||
datasourceReq.setDatabaseId(2L);
|
||||
|
||||
List<Identify> identifiers = new ArrayList<>();
|
||||
identifiers.add(new Identify("用户名_a", IdentifyTypeEnum.primary.name(), "user_name_a"));
|
||||
datasourceReq.setIdentifiers(identifiers);
|
||||
|
||||
List<Dim> dimensions = new ArrayList<>();
|
||||
Dim dimension1 = new Dim("", "imp_date_a", DimensionTypeEnum.time.name(), 0);
|
||||
dimension1.setTypeParams(new DimensionTimeTypeParams());
|
||||
dimensions.add(dimension1);
|
||||
Dim dimension2 = new Dim("", "page_a", DimensionTypeEnum.categorical.name(), 0);
|
||||
dimension2.setExpr("page_a");
|
||||
dimensions.add(dimension2);
|
||||
datasourceReq.setDimensions(dimensions);
|
||||
|
||||
List<Measure> measures = new ArrayList<>();
|
||||
Measure measure1 = new Measure("访问次数_a", "pv_a", AggOperatorEnum.SUM.name(), 1);
|
||||
measures.add(measure1);
|
||||
|
||||
Measure measure2 = new Measure("访问人数_a", "uv_a", AggOperatorEnum.COUNT_DISTINCT.name(), 1);
|
||||
measures.add(measure2);
|
||||
|
||||
datasourceReq.setMeasures(measures);
|
||||
datasourceReq.setSqlQuery("SELECT imp_date_a, user_name_a, page_a, 1 as pv_a, user_name "
|
||||
+ "as uv_a FROM s2_pv_uv_statis");
|
||||
datasourceReq.setQueryType("sql_query");
|
||||
datasourceReq.setModelId(1L);
|
||||
datasourceReq.setFilterSql("where user_name = 'tom'");
|
||||
return datasourceReq;
|
||||
}
|
||||
|
||||
private DatasourceResp buildExpectedDatasourceResp() {
|
||||
DatasourceResp datasourceResp = new DatasourceResp();
|
||||
datasourceResp.setName("PVUV统计");
|
||||
datasourceResp.setBizName("s2_pv_uv_statis");
|
||||
datasourceResp.setDescription("PVUV统计");
|
||||
datasourceResp.setDatabaseId(1L);
|
||||
DatasourceDetail datasourceDetail = new DatasourceDetail();
|
||||
List<Identify> identifiers = new ArrayList<>();
|
||||
identifiers.add(new Identify("用户名", IdentifyTypeEnum.primary.name(), "user_name"));
|
||||
datasourceDetail.setIdentifiers(identifiers);
|
||||
|
||||
List<Dim> dimensions = new ArrayList<>();
|
||||
Dim dimension1 = new Dim("", "imp_date", DimensionTypeEnum.time.name(), 0);
|
||||
dimension1.setTypeParams(new DimensionTimeTypeParams());
|
||||
dimensions.add(dimension1);
|
||||
Dim dimension2 = new Dim("", "page", DimensionTypeEnum.categorical.name(), 0);
|
||||
dimension2.setExpr("page");
|
||||
dimensions.add(dimension2);
|
||||
datasourceDetail.setDimensions(dimensions);
|
||||
|
||||
List<Measure> measures = new ArrayList<>();
|
||||
Measure measure1 = new Measure("访问次数", "s2_pv_uv_statis_pv", AggOperatorEnum.SUM.name(), 1);
|
||||
measure1.setExpr("pv");
|
||||
measures.add(measure1);
|
||||
|
||||
Measure measure2 = new Measure("访问人数", "s2_pv_uv_statis_uv", AggOperatorEnum.COUNT_DISTINCT.name(), 1);
|
||||
measure2.setExpr("uv");
|
||||
measures.add(measure2);
|
||||
|
||||
datasourceDetail.setMeasures(measures);
|
||||
datasourceDetail.setSqlQuery("SELECT imp_date, user_name, page, 1 as pv, user_name as uv FROM s2_pv_uv_statis");
|
||||
datasourceDetail.setQueryType("sql_query");
|
||||
datasourceResp.setDatasourceDetail(datasourceDetail);
|
||||
datasourceResp.setModelId(1L);
|
||||
datasourceResp.setFilterSql("where user_name = 'alice'");
|
||||
return datasourceResp;
|
||||
}
|
||||
|
||||
private DatasourceResp buildExpectedDatasourceResp_update() {
|
||||
DatasourceResp datasourceResp = new DatasourceResp();
|
||||
datasourceResp.setName("PVUV统计_a");
|
||||
datasourceResp.setBizName("s2_pv_uv_statis_a");
|
||||
datasourceResp.setDescription("PVUV统计_a");
|
||||
datasourceResp.setDatabaseId(2L);
|
||||
DatasourceDetail datasourceDetail = new DatasourceDetail();
|
||||
List<Identify> identifiers = new ArrayList<>();
|
||||
identifiers.add(new Identify("用户名_a", IdentifyTypeEnum.primary.name(), "user_name_a"));
|
||||
datasourceDetail.setIdentifiers(identifiers);
|
||||
|
||||
List<Dim> dimensions = new ArrayList<>();
|
||||
Dim dimension1 = new Dim("", "imp_date_a", DimensionTypeEnum.time.name(), 0);
|
||||
dimension1.setTypeParams(new DimensionTimeTypeParams());
|
||||
dimensions.add(dimension1);
|
||||
Dim dimension2 = new Dim("", "page_a", DimensionTypeEnum.categorical.name(), 0);
|
||||
dimension2.setExpr("page_a");
|
||||
dimensions.add(dimension2);
|
||||
datasourceDetail.setDimensions(dimensions);
|
||||
|
||||
List<Measure> measures = new ArrayList<>();
|
||||
Measure measure1 = new Measure("访问次数_a", "s2_pv_uv_statis_a_pv_a",
|
||||
AggOperatorEnum.SUM.name(), 1);
|
||||
measure1.setExpr("pv_a");
|
||||
measures.add(measure1);
|
||||
|
||||
Measure measure2 = new Measure("访问人数_a", "s2_pv_uv_statis_a_uv_a",
|
||||
AggOperatorEnum.COUNT_DISTINCT.name(), 1);
|
||||
measure2.setExpr("uv_a");
|
||||
measures.add(measure2);
|
||||
|
||||
datasourceDetail.setMeasures(measures);
|
||||
datasourceDetail.setSqlQuery("SELECT imp_date_a, user_name_a, page_a, 1 as pv_a, "
|
||||
+ "user_name as uv_a FROM s2_pv_uv_statis");
|
||||
datasourceDetail.setQueryType("sql_query");
|
||||
datasourceResp.setDatasourceDetail(datasourceDetail);
|
||||
datasourceResp.setModelId(1L);
|
||||
datasourceResp.setFilterSql("where user_name = 'tom'");
|
||||
return datasourceResp;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
package com.tencent.supersonic.semantic.model.application;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authentication.service.UserService;
|
||||
import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.DimensionTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.IdentifyTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Dim;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DimensionTimeTypeParams;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.ModelDetail;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatabaseService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DomainService;
|
||||
import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelRelaService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.dataobject.ModelDO;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.DateInfoRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.repository.ModelRepository;
|
||||
import com.tencent.supersonic.semantic.model.domain.utils.ModelConverter;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class ModelServiceImplTest {
|
||||
|
||||
@Test
|
||||
void createModel() throws Exception {
|
||||
ModelRepository modelRepository = Mockito.mock(ModelRepository.class);
|
||||
ModelService modelService = mockModelService(modelRepository);
|
||||
ModelResp actualModelResp = modelService.createModel(
|
||||
mockModelReq(), User.getFakeUser());
|
||||
ModelResp expectedModelResp = buildExpectedModelResp();
|
||||
Assertions.assertEquals(expectedModelResp, actualModelResp);
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateModel() throws Exception {
|
||||
ModelRepository modelRepository = Mockito.mock(ModelRepository.class);
|
||||
ModelService modelService = mockModelService(modelRepository);
|
||||
ModelReq modelReq = mockModelReq_update();
|
||||
ModelDO modelDO = ModelConverter.convert(mockModelReq(), User.getFakeUser());
|
||||
when(modelRepository.getModelById(modelReq.getId())).thenReturn(modelDO);
|
||||
User user = User.getFakeUser();
|
||||
user.setName("alice");
|
||||
ModelResp actualModelResp = modelService.updateModel(modelReq, user);
|
||||
ModelResp expectedModelResp = buildExpectedModelResp_update();
|
||||
Assertions.assertEquals(expectedModelResp, actualModelResp);
|
||||
Assertions.assertEquals("admin", actualModelResp.getCreatedBy());
|
||||
Assertions.assertEquals("alice", actualModelResp.getUpdatedBy());
|
||||
}
|
||||
|
||||
|
||||
private ModelService mockModelService(ModelRepository modelRepository) {
|
||||
MetricService metricService = Mockito.mock(MetricService.class);
|
||||
DimensionService dimensionService = Mockito.mock(DimensionService.class);
|
||||
DatabaseService databaseService = Mockito.mock(DatabaseService.class);
|
||||
DomainService domainService = Mockito.mock(DomainService.class);
|
||||
UserService userService = Mockito.mock(UserService.class);
|
||||
ModelRelaService modelRelaService = Mockito.mock(ModelRelaService.class);
|
||||
DateInfoRepository dateInfoRepository = Mockito.mock(DateInfoRepository.class);
|
||||
return new ModelServiceImpl(modelRepository, databaseService,
|
||||
dimensionService, metricService, modelRelaService, domainService, userService, dateInfoRepository);
|
||||
}
|
||||
|
||||
private ModelReq mockModelReq() {
|
||||
ModelReq modelReq = new ModelReq();
|
||||
modelReq.setId(1L);
|
||||
modelReq.setName("PVUV统计");
|
||||
modelReq.setBizName("s2_pv_uv_statis");
|
||||
modelReq.setDescription("PVUV统计");
|
||||
modelReq.setDatabaseId(1L);
|
||||
modelReq.setAlias("访问次数统计,PVUV统计");
|
||||
modelReq.setAdmins(Lists.newArrayList("admin", "tom"));
|
||||
modelReq.setViewers(Lists.newArrayList("alice", "lucy"));
|
||||
ModelDetail modelDetail = new ModelDetail();
|
||||
List<Identify> identifiers = new ArrayList<>();
|
||||
identifiers.add(new Identify("用户名", IdentifyTypeEnum.primary.name(), "user_name"));
|
||||
modelDetail.setIdentifiers(identifiers);
|
||||
List<Dim> dimensions = new ArrayList<>();
|
||||
Dim dimension1 = new Dim("", "imp_date", DimensionTypeEnum.time.name(), 0);
|
||||
dimension1.setTypeParams(new DimensionTimeTypeParams());
|
||||
dimensions.add(dimension1);
|
||||
Dim dimension2 = new Dim("", "page", DimensionTypeEnum.categorical.name(), 0);
|
||||
dimension2.setExpr("page");
|
||||
dimensions.add(dimension2);
|
||||
modelDetail.setDimensions(dimensions);
|
||||
List<Measure> measures = new ArrayList<>();
|
||||
Measure measure1 = new Measure("访问次数", "pv", AggOperatorEnum.SUM.name(), 1);
|
||||
measures.add(measure1);
|
||||
Measure measure2 = new Measure("访问人数", "uv", AggOperatorEnum.COUNT_DISTINCT.name(), 1);
|
||||
measures.add(measure2);
|
||||
modelDetail.setMeasures(measures);
|
||||
modelDetail.setSqlQuery("SELECT imp_date, user_name, page, 1 as pv, user_name as uv FROM s2_pv_uv_statis");
|
||||
modelDetail.setQueryType("sql_query");
|
||||
modelReq.setDomainId(1L);
|
||||
modelReq.setFilterSql("where user_name = 'alice'");
|
||||
modelReq.setModelDetail(modelDetail);
|
||||
return modelReq;
|
||||
}
|
||||
|
||||
private ModelReq mockModelReq_update() {
|
||||
ModelReq modelReq = new ModelReq();
|
||||
modelReq.setId(1L);
|
||||
modelReq.setName("PVUV统计_a");
|
||||
modelReq.setBizName("s2_pv_uv_statis_a");
|
||||
modelReq.setDescription("PVUV统计_a");
|
||||
modelReq.setDatabaseId(2L);
|
||||
modelReq.setDomainId(1L);
|
||||
modelReq.setAlias("访问次数统计,PVUV统计");
|
||||
modelReq.setAdmins(Lists.newArrayList("admin"));
|
||||
modelReq.setViewers(Lists.newArrayList("alice"));
|
||||
ModelDetail modelDetail = new ModelDetail();
|
||||
List<Identify> identifiers = new ArrayList<>();
|
||||
identifiers.add(new Identify("用户名_a", IdentifyTypeEnum.primary.name(), "user_name_a"));
|
||||
modelDetail.setIdentifiers(identifiers);
|
||||
|
||||
List<Dim> dimensions = new ArrayList<>();
|
||||
Dim dimension1 = new Dim("", "imp_date_a", DimensionTypeEnum.time.name(), 0);
|
||||
dimension1.setTypeParams(new DimensionTimeTypeParams());
|
||||
dimensions.add(dimension1);
|
||||
Dim dimension2 = new Dim("", "page_a", DimensionTypeEnum.categorical.name(), 0);
|
||||
dimension2.setExpr("page_a");
|
||||
dimensions.add(dimension2);
|
||||
modelDetail.setDimensions(dimensions);
|
||||
|
||||
List<Measure> measures = new ArrayList<>();
|
||||
Measure measure1 = new Measure("访问次数_a", "pv_a", AggOperatorEnum.SUM.name(), 1);
|
||||
measures.add(measure1);
|
||||
|
||||
Measure measure2 = new Measure("访问人数_a", "uv_a", AggOperatorEnum.COUNT_DISTINCT.name(), 1);
|
||||
measures.add(measure2);
|
||||
|
||||
modelDetail.setMeasures(measures);
|
||||
modelDetail.setSqlQuery("SELECT imp_date_a, user_name_a, page_a, 1 as pv_a, user_name "
|
||||
+ "as uv_a FROM s2_pv_uv_statis");
|
||||
modelDetail.setQueryType("sql_query");
|
||||
modelReq.setDomainId(1L);
|
||||
modelReq.setFilterSql("where user_name = 'tom'");
|
||||
modelReq.setModelDetail(modelDetail);
|
||||
return modelReq;
|
||||
}
|
||||
|
||||
private ModelResp buildExpectedModelResp() {
|
||||
ModelResp modelResp = new ModelResp();
|
||||
modelResp.setName("PVUV统计");
|
||||
modelResp.setBizName("s2_pv_uv_statis");
|
||||
modelResp.setDescription("PVUV统计");
|
||||
modelResp.setDatabaseId(1L);
|
||||
modelResp.setDomainId(1L);
|
||||
modelResp.setAlias("访问次数统计,PVUV统计");
|
||||
modelResp.setAdmins(Lists.newArrayList("admin", "tom"));
|
||||
modelResp.setViewers(Lists.newArrayList("alice", "lucy"));
|
||||
ModelDetail modelDetail = new ModelDetail();
|
||||
List<Identify> identifiers = new ArrayList<>();
|
||||
identifiers.add(new Identify("用户名", IdentifyTypeEnum.primary.name(), "user_name"));
|
||||
modelDetail.setIdentifiers(identifiers);
|
||||
|
||||
List<Dim> dimensions = new ArrayList<>();
|
||||
Dim dimension1 = new Dim("", "imp_date", DimensionTypeEnum.time.name(), 0);
|
||||
dimension1.setTypeParams(new DimensionTimeTypeParams());
|
||||
dimensions.add(dimension1);
|
||||
Dim dimension2 = new Dim("", "page", DimensionTypeEnum.categorical.name(), 0);
|
||||
dimension2.setExpr("page");
|
||||
dimensions.add(dimension2);
|
||||
modelDetail.setDimensions(dimensions);
|
||||
|
||||
List<Measure> measures = new ArrayList<>();
|
||||
Measure measure1 = new Measure("访问次数", "s2_pv_uv_statis_pv", AggOperatorEnum.SUM.name(), 1);
|
||||
measure1.setExpr("pv");
|
||||
measures.add(measure1);
|
||||
|
||||
Measure measure2 = new Measure("访问人数", "s2_pv_uv_statis_uv", AggOperatorEnum.COUNT_DISTINCT.name(), 1);
|
||||
measure2.setExpr("uv");
|
||||
measures.add(measure2);
|
||||
|
||||
modelDetail.setMeasures(measures);
|
||||
modelDetail.setSqlQuery("SELECT imp_date, user_name, page, 1 as pv, user_name as uv FROM s2_pv_uv_statis");
|
||||
modelDetail.setQueryType("sql_query");
|
||||
modelResp.setModelDetail(modelDetail);
|
||||
modelResp.setId(1L);
|
||||
modelResp.setFilterSql("where user_name = 'alice'");
|
||||
return modelResp;
|
||||
}
|
||||
|
||||
private ModelResp buildExpectedModelResp_update() {
|
||||
ModelResp modelResp = new ModelResp();
|
||||
modelResp.setName("PVUV统计_a");
|
||||
modelResp.setBizName("s2_pv_uv_statis_a");
|
||||
modelResp.setDescription("PVUV统计_a");
|
||||
modelResp.setDatabaseId(2L);
|
||||
modelResp.setDomainId(1L);
|
||||
modelResp.setAlias("访问次数统计,PVUV统计");
|
||||
modelResp.setAdmins(Lists.newArrayList("admin"));
|
||||
modelResp.setViewers(Lists.newArrayList("alice"));
|
||||
ModelDetail modelDetail = new ModelDetail();
|
||||
List<Identify> identifiers = new ArrayList<>();
|
||||
identifiers.add(new Identify("用户名_a", IdentifyTypeEnum.primary.name(), "user_name_a"));
|
||||
modelDetail.setIdentifiers(identifiers);
|
||||
|
||||
List<Dim> dimensions = new ArrayList<>();
|
||||
Dim dimension1 = new Dim("", "imp_date_a", DimensionTypeEnum.time.name(), 0);
|
||||
dimension1.setTypeParams(new DimensionTimeTypeParams());
|
||||
dimensions.add(dimension1);
|
||||
Dim dimension2 = new Dim("", "page_a", DimensionTypeEnum.categorical.name(), 0);
|
||||
dimension2.setExpr("page_a");
|
||||
dimensions.add(dimension2);
|
||||
modelDetail.setDimensions(dimensions);
|
||||
|
||||
List<Measure> measures = new ArrayList<>();
|
||||
Measure measure1 = new Measure("访问次数_a", "s2_pv_uv_statis_a_pv_a",
|
||||
AggOperatorEnum.SUM.name(), 1);
|
||||
measure1.setExpr("pv_a");
|
||||
measures.add(measure1);
|
||||
|
||||
Measure measure2 = new Measure("访问人数_a", "s2_pv_uv_statis_a_uv_a",
|
||||
AggOperatorEnum.COUNT_DISTINCT.name(), 1);
|
||||
measure2.setExpr("uv_a");
|
||||
measures.add(measure2);
|
||||
|
||||
modelDetail.setMeasures(measures);
|
||||
modelDetail.setSqlQuery("SELECT imp_date_a, user_name_a, page_a, 1 as pv_a, "
|
||||
+ "user_name as uv_a FROM s2_pv_uv_statis");
|
||||
modelDetail.setQueryType("sql_query");
|
||||
modelResp.setModelDetail(modelDetail);
|
||||
modelResp.setId(1L);
|
||||
modelResp.setFilterSql("where user_name = 'tom'");
|
||||
return modelResp;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -85,8 +85,9 @@ public class MaterializationQuery implements QueryOptimizer {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (Objects.isNull(queryStructCmd) || Objects.isNull(queryStatement) || Objects.isNull(
|
||||
queryStructCmd.getModelId()) || Objects.isNull(
|
||||
if (Objects.isNull(queryStructCmd) || Objects.isNull(queryStatement)
|
||||
|| CollectionUtils.isEmpty(queryStructCmd.getModelIds())
|
||||
|| Objects.isNull(
|
||||
queryStructCmd.getDateInfo())) {
|
||||
return;
|
||||
}
|
||||
@@ -172,10 +173,11 @@ public class MaterializationQuery implements QueryOptimizer {
|
||||
ImmutablePair<String, String> timeRange = queryStructUtils.getBeginEndTime(queryStructReq);
|
||||
String start = timeRange.left;
|
||||
String end = timeRange.right;
|
||||
Long modelId = queryStructReq.getModelId();
|
||||
//todo
|
||||
Long modelId = 1L;
|
||||
List<MaterializationResp> materializationResps = materializationConfService.getMaterializationByModel(modelId);
|
||||
List<DimensionResp> dimensionResps = catalog.getDimensions(modelId);
|
||||
List<MetricResp> metrics = catalog.getMetrics(modelId);
|
||||
List<DimensionResp> dimensionResps = catalog.getDimensions(queryStructReq.getModelIds());
|
||||
List<MetricResp> metrics = catalog.getMetrics(queryStructReq.getModelIds());
|
||||
Set<String> fields = new HashSet<>();
|
||||
|
||||
if (Objects.nonNull(metricReq.getWhere()) && !metricReq.getWhere().isEmpty()) {
|
||||
|
||||
@@ -41,6 +41,7 @@ public class CalciteSqlParser implements SqlParser {
|
||||
semanticSchema.setDatasource(semanticModel.getDatasourceMap());
|
||||
semanticSchema.setDimension(semanticModel.getDimensionMap());
|
||||
semanticSchema.setMetric(semanticModel.getMetrics());
|
||||
semanticSchema.setJoinRelations(semanticModel.getJoinRelations());
|
||||
return semanticSchema;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ package com.tencent.supersonic.semantic.query.parser.calcite;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DatasourceYamlTpl;
|
||||
import com.tencent.supersonic.common.pojo.ModelRela;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DataModelYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionTimeTypeParamsTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.DimensionYamlTpl;
|
||||
import com.tencent.supersonic.semantic.api.model.yaml.IdentifyYamlTpl;
|
||||
@@ -17,12 +19,14 @@ import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.DataType;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Dimension;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.DimensionTimeTypeParams;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Identify;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.JoinRelation;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Measure;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Metric;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.MetricTypeParams;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.SemanticModel;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSchema;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -34,6 +38,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.tuple.Triple;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
@@ -57,20 +62,27 @@ public class SemanticSchemaManager {
|
||||
public SemanticModel reload(String rootPath) {
|
||||
SemanticModel semanticModel = new SemanticModel();
|
||||
semanticModel.setRootPath(rootPath);
|
||||
Map<Long, String> modelFullPathMap = catalog.getModelFullPath();
|
||||
log.info("modelFullPathMap {}", modelFullPathMap);
|
||||
Set<Long> modelIds = modelFullPathMap.entrySet().stream().filter(e -> e.getValue().startsWith(rootPath))
|
||||
.map(Entry::getKey).collect(Collectors.toSet());
|
||||
//Map<Long, String> modelFullPathMap = catalog.getModelFullPath();
|
||||
//log.info("modelFullPathMap {}", modelFullPathMap);
|
||||
//Set<Long> modelIds = modelFullPathMap.entrySet().stream().filter(e -> e.getValue().startsWith(rootPath))
|
||||
// .map(Entry::getKey).collect(Collectors.toSet());
|
||||
Set<Long> modelIds = Arrays.stream(rootPath.split(",")).map(s -> Long.parseLong(s.trim()))
|
||||
.collect(Collectors.toSet());
|
||||
if (modelIds.isEmpty()) {
|
||||
log.error("get modelIds empty {}", rootPath);
|
||||
return semanticModel;
|
||||
}
|
||||
Map<String, List<DimensionYamlTpl>> dimensionYamlTpls = new HashMap<>();
|
||||
List<DatasourceYamlTpl> datasourceYamlTpls = new ArrayList<>();
|
||||
List<DataModelYamlTpl> dataModelYamlTpls = new ArrayList<>();
|
||||
List<MetricYamlTpl> metricYamlTpls = new ArrayList<>();
|
||||
catalog.getModelYamlTplByModelIds(modelIds, dimensionYamlTpls, datasourceYamlTpls, metricYamlTpls);
|
||||
if (!datasourceYamlTpls.isEmpty()) {
|
||||
Map<String, DataSource> dataSourceMap = datasourceYamlTpls.stream().map(d -> getDatasource(d))
|
||||
Map<Long, String> modelIdName = new HashMap<>();
|
||||
catalog.getModelYamlTplByModelIds(modelIds, dimensionYamlTpls, dataModelYamlTpls, metricYamlTpls, modelIdName);
|
||||
List<ModelRela> modelRelas = catalog.getModelRela(new ArrayList<>(modelIds));
|
||||
if (!CollectionUtils.isEmpty(modelRelas)) {
|
||||
semanticModel.setJoinRelations(getJoinRelation(modelRelas, modelIdName));
|
||||
}
|
||||
if (!dataModelYamlTpls.isEmpty()) {
|
||||
Map<String, DataSource> dataSourceMap = dataModelYamlTpls.stream().map(d -> getDatasource(d))
|
||||
.collect(Collectors.toMap(DataSource::getName, item -> item, (k1, k2) -> k1));
|
||||
semanticModel.setDatasourceMap(dataSourceMap);
|
||||
}
|
||||
@@ -107,7 +119,7 @@ public class SemanticSchemaManager {
|
||||
}
|
||||
|
||||
|
||||
public static DataSource getDatasource(final DatasourceYamlTpl d) {
|
||||
public static DataSource getDatasource(final DataModelYamlTpl d) {
|
||||
DataSource datasource = DataSource.builder().sourceId(d.getSourceId()).sqlQuery(d.getSqlQuery())
|
||||
.name(d.getName()).tableQuery(d.getTableQuery()).identifiers(getIdentify(d.getIdentifiers()))
|
||||
.measures(getMeasures(d.getMeasures())).dimensions(getDimensions(d.getDimensions())).build();
|
||||
@@ -200,6 +212,25 @@ public class SemanticSchemaManager {
|
||||
return identifies;
|
||||
}
|
||||
|
||||
private static List<JoinRelation> getJoinRelation(List<ModelRela> modelRelas, Map<Long, String> modelIdName) {
|
||||
List<JoinRelation> joinRelations = new ArrayList<>();
|
||||
modelRelas.stream().forEach(r -> {
|
||||
if (modelIdName.containsKey(r.getFromModelId()) && modelIdName.containsKey(r.getToModelId())) {
|
||||
JoinRelation joinRelation = JoinRelation.builder().left(modelIdName.get(r.getFromModelId()))
|
||||
.right(modelIdName.get(r.getToModelId())).joinType(r.getJoinType()).build();
|
||||
List<Triple<String, String, String>> conditions = new ArrayList<>();
|
||||
r.getJoinConditions().stream().forEach(rr -> {
|
||||
if (FilterOperatorEnum.isValueCompare(rr.getOperator())) {
|
||||
conditions.add(Triple.of(rr.getLeftField(), rr.getOperator().getValue(), rr.getRightField()));
|
||||
}
|
||||
});
|
||||
joinRelation.setJoinCondition(conditions);
|
||||
joinRelations.add(joinRelation);
|
||||
}
|
||||
});
|
||||
return joinRelations;
|
||||
}
|
||||
|
||||
|
||||
public static void update(SemanticSchema schema, List<Metric> metric) throws Exception {
|
||||
if (schema != null) {
|
||||
|
||||
@@ -15,18 +15,19 @@ import com.tencent.supersonic.semantic.query.parser.calcite.sql.render.FilterRen
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.sql.render.OutputRender;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.sql.render.SourceRender;
|
||||
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
|
||||
import org.apache.calcite.sql.SqlNode;
|
||||
import org.apache.calcite.sql.validate.SqlValidatorScope;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Objects;
|
||||
import java.util.Stack;
|
||||
import org.apache.calcite.sql.SqlNode;
|
||||
import org.apache.calcite.sql.validate.SqlValidatorScope;
|
||||
|
||||
public class AggPlanner implements Planner {
|
||||
|
||||
private MetricReq metricCommand;
|
||||
private MetricReq metricReq;
|
||||
private SemanticSchema schema;
|
||||
private SqlValidatorScope scope;
|
||||
private Stack<TableView> dataSets = new Stack<>();
|
||||
@@ -61,13 +62,13 @@ public class AggPlanner implements Planner {
|
||||
while (it.hasNext()) {
|
||||
Renderer renderer = it.next();
|
||||
if (previous != null) {
|
||||
previous.render(metricCommand, datasource, scope, schema, !isAgg);
|
||||
previous.render(metricReq, datasource, scope, schema, !isAgg);
|
||||
renderer.setTable(previous.builderAs(DataSourceNode.getNames(datasource) + "_" + String.valueOf(i)));
|
||||
i++;
|
||||
}
|
||||
previous = renderer;
|
||||
}
|
||||
builders.getLast().render(metricCommand, datasource, scope, schema, !isAgg);
|
||||
builders.getLast().render(metricReq, datasource, scope, schema, !isAgg);
|
||||
parserNode = builders.getLast().builder();
|
||||
|
||||
|
||||
@@ -75,7 +76,7 @@ public class AggPlanner implements Planner {
|
||||
|
||||
|
||||
private List<DataSource> getMatchDataSource(SqlValidatorScope scope) throws Exception {
|
||||
return DataSourceNode.getMatchDataSources(scope, schema, metricCommand);
|
||||
return DataSourceNode.getMatchDataSources(scope, schema, metricReq);
|
||||
}
|
||||
|
||||
private boolean getAgg(DataSource dataSource) {
|
||||
@@ -85,7 +86,7 @@ public class AggPlanner implements Planner {
|
||||
// default by dataSource time aggregation
|
||||
if (Objects.nonNull(dataSource.getAggTime()) && !dataSource.getAggTime().equalsIgnoreCase(
|
||||
Constants.DIMENSION_TYPE_TIME_GRANULARITY_NONE)) {
|
||||
if (!metricCommand.isNativeQuery()) {
|
||||
if (!metricReq.isNativeQuery()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -95,15 +96,15 @@ public class AggPlanner implements Planner {
|
||||
|
||||
@Override
|
||||
public void explain(QueryStatement queryStatement, AggOption aggOption) throws Exception {
|
||||
this.metricCommand = queryStatement.getMetricReq();
|
||||
if (metricCommand.getMetrics() == null) {
|
||||
metricCommand.setMetrics(new ArrayList<>());
|
||||
this.metricReq = queryStatement.getMetricReq();
|
||||
if (metricReq.getMetrics() == null) {
|
||||
metricReq.setMetrics(new ArrayList<>());
|
||||
}
|
||||
if (metricCommand.getDimensions() == null) {
|
||||
metricCommand.setDimensions(new ArrayList<>());
|
||||
if (metricReq.getDimensions() == null) {
|
||||
metricReq.setDimensions(new ArrayList<>());
|
||||
}
|
||||
if (metricCommand.getLimit() == null) {
|
||||
metricCommand.setLimit(0L);
|
||||
if (metricReq.getLimit() == null) {
|
||||
metricReq.setLimit(0L);
|
||||
}
|
||||
this.aggOption = aggOption;
|
||||
// build a parse Node
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.tencent.supersonic.semantic.query.parser.calcite.s2sql;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.tuple.Triple;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class JoinRelation {
|
||||
|
||||
private String left;
|
||||
private String right;
|
||||
private String joinType;
|
||||
private List<Triple<String, String, String>> joinCondition;
|
||||
|
||||
}
|
||||
@@ -14,4 +14,5 @@ public class SemanticModel {
|
||||
private Map<String, DataSource> datasourceMap = new HashMap<>();
|
||||
private Map<String, List<Dimension>> dimensionMap = new HashMap<>();
|
||||
private List<Materialization> materializationList = new ArrayList<>();
|
||||
private List<JoinRelation> joinRelations;
|
||||
}
|
||||
|
||||
@@ -3,17 +3,19 @@ package com.tencent.supersonic.semantic.query.parser.calcite.schema;
|
||||
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.DataSource;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Dimension;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.JoinRelation;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Materialization;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Metric;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.SemanticModel;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.calcite.schema.Schema;
|
||||
import org.apache.calcite.schema.SchemaVersion;
|
||||
import org.apache.calcite.schema.Table;
|
||||
import org.apache.calcite.schema.impl.AbstractSchema;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SemanticSchema extends AbstractSchema {
|
||||
|
||||
private final String rootPath;
|
||||
@@ -21,6 +23,8 @@ public class SemanticSchema extends AbstractSchema {
|
||||
|
||||
private SemanticModel semanticModel = new SemanticModel();
|
||||
|
||||
private List<JoinRelation> joinRelations;
|
||||
|
||||
|
||||
private SemanticSchema(String rootPath, Map<String, Table> tableMap) {
|
||||
this.rootPath = rootPath;
|
||||
@@ -84,6 +88,14 @@ public class SemanticSchema extends AbstractSchema {
|
||||
return semanticModel.getMaterializationList();
|
||||
}
|
||||
|
||||
public void setJoinRelations(List<JoinRelation> joinRelations) {
|
||||
this.joinRelations = joinRelations;
|
||||
}
|
||||
|
||||
public List<JoinRelation> getJoinRelations() {
|
||||
return joinRelations;
|
||||
}
|
||||
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
package com.tencent.supersonic.semantic.query.parser.calcite.sql.node;
|
||||
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.semantic.api.query.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.Configuration;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Constants;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.DataSource;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Dimension;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.JoinRelation;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSchema;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.sql.node.extend.LateralViewExplodeNode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.calcite.sql.SqlBasicCall;
|
||||
import org.apache.calcite.sql.SqlDataTypeSpec;
|
||||
import org.apache.calcite.sql.SqlNode;
|
||||
import org.apache.calcite.sql.SqlNodeList;
|
||||
import org.apache.calcite.sql.SqlUserDefinedTypeNameSpec;
|
||||
import org.apache.calcite.sql.parser.SqlParser;
|
||||
import org.apache.calcite.sql.parser.SqlParserPos;
|
||||
import org.apache.calcite.sql.validate.SqlValidatorScope;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
@@ -19,16 +32,6 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.calcite.sql.SqlBasicCall;
|
||||
import org.apache.calcite.sql.SqlDataTypeSpec;
|
||||
import org.apache.calcite.sql.SqlNode;
|
||||
import org.apache.calcite.sql.SqlNodeList;
|
||||
import org.apache.calcite.sql.SqlUserDefinedTypeNameSpec;
|
||||
import org.apache.calcite.sql.parser.SqlParser;
|
||||
import org.apache.calcite.sql.parser.SqlParserPos;
|
||||
import org.apache.calcite.sql.validate.SqlValidatorScope;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Slf4j
|
||||
public class DataSourceNode extends SemanticNode {
|
||||
@@ -159,21 +162,26 @@ public class DataSourceNode extends SemanticNode {
|
||||
return dataSources;
|
||||
}
|
||||
// find all dataSource has the same identifiers
|
||||
Set<String> baseIdentifiers = baseDataSource.getIdentifiers().stream().map(i -> i.getName())
|
||||
.collect(Collectors.toSet());
|
||||
if (baseIdentifiers.isEmpty()) {
|
||||
throw new Exception("datasource error : " + baseDataSource.getName() + " miss identifier");
|
||||
}
|
||||
List<DataSource> linkDataSources = getLinkDataSources(baseIdentifiers, queryDimension, measures,
|
||||
List<DataSource> linkDataSources = getLinkDataSourcesByJoinRelation(queryDimension, measures,
|
||||
baseDataSource, schema);
|
||||
if (linkDataSources.isEmpty()) {
|
||||
throw new Exception(
|
||||
String.format("not find the match datasource : dimension[%s],measure[%s]", queryDimension,
|
||||
measures));
|
||||
if (CollectionUtils.isEmpty(linkDataSources)) {
|
||||
log.info("baseDataSource get by identifiers ");
|
||||
Set<String> baseIdentifiers = baseDataSource.getIdentifiers().stream().map(i -> i.getName())
|
||||
.collect(Collectors.toSet());
|
||||
if (baseIdentifiers.isEmpty()) {
|
||||
throw new Exception("datasource error : " + baseDataSource.getName() + " miss identifier");
|
||||
}
|
||||
linkDataSources = getLinkDataSources(baseIdentifiers, queryDimension, measures,
|
||||
baseDataSource, schema);
|
||||
if (linkDataSources.isEmpty()) {
|
||||
throw new Exception(
|
||||
String.format("not find the match datasource : dimension[%s],measure[%s]", queryDimension,
|
||||
measures));
|
||||
}
|
||||
}
|
||||
log.debug("linkDataSources {}", linkDataSources);
|
||||
|
||||
dataSources.addAll(linkDataSources);
|
||||
return linkDataSources;
|
||||
//dataSources.addAll(linkDataSources);
|
||||
}
|
||||
|
||||
return dataSources;
|
||||
@@ -208,6 +216,69 @@ public class DataSourceNode extends SemanticNode {
|
||||
return isAllMatch;
|
||||
}
|
||||
|
||||
private static List<DataSource> getLinkDataSourcesByJoinRelation(Set<String> queryDimension, List<String> measures,
|
||||
DataSource baseDataSource, SemanticSchema schema) {
|
||||
Set<String> linkDataSourceName = new HashSet<>();
|
||||
List<DataSource> linkDataSources = new ArrayList<>();
|
||||
Set<String> before = new HashSet<>();
|
||||
before.add(baseDataSource.getName());
|
||||
if (!CollectionUtils.isEmpty(schema.getJoinRelations())) {
|
||||
for (JoinRelation joinRelation : schema.getJoinRelations()) {
|
||||
if (!before.contains(joinRelation.getLeft()) && !before.contains(joinRelation.getRight())) {
|
||||
continue;
|
||||
}
|
||||
boolean isMatch = false;
|
||||
boolean isRight = before.contains(joinRelation.getLeft());
|
||||
DataSource other = isRight ? schema.getDatasource().get(joinRelation.getRight())
|
||||
: schema.getDatasource().get(joinRelation.getLeft());
|
||||
if (!queryDimension.isEmpty()) {
|
||||
Set<String> linkDimension = other.getDimensions().stream().map(dd -> dd.getName())
|
||||
.collect(Collectors.toSet());
|
||||
other.getIdentifiers().stream().forEach(i -> linkDimension.add(i.getName()));
|
||||
linkDimension.retainAll(queryDimension);
|
||||
if (!linkDimension.isEmpty()) {
|
||||
isMatch = true;
|
||||
}
|
||||
}
|
||||
Set<String> linkMeasure = other.getMeasures().stream().map(mm -> mm.getName())
|
||||
.collect(Collectors.toSet());
|
||||
linkMeasure.retainAll(measures);
|
||||
if (!linkMeasure.isEmpty()) {
|
||||
isMatch = true;
|
||||
}
|
||||
if (!isMatch && schema.getDimension().containsKey(other.getName())) {
|
||||
Set<String> linkDimension = schema.getDimension().get(other.getName()).stream()
|
||||
.map(dd -> dd.getName())
|
||||
.collect(Collectors.toSet());
|
||||
linkDimension.retainAll(queryDimension);
|
||||
if (!linkDimension.isEmpty()) {
|
||||
isMatch = true;
|
||||
}
|
||||
}
|
||||
if (isMatch) {
|
||||
linkDataSourceName.add(other.getName());
|
||||
before.add(other.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(linkDataSourceName)) {
|
||||
Map<String, Long> orders = new HashMap<>();
|
||||
linkDataSourceName.add(baseDataSource.getName());
|
||||
orders.put(baseDataSource.getName(), 0L);
|
||||
for (JoinRelation joinRelation : schema.getJoinRelations()) {
|
||||
if (linkDataSourceName.contains(joinRelation.getLeft()) && linkDataSourceName.contains(
|
||||
joinRelation.getRight())) {
|
||||
orders.put(joinRelation.getLeft(), 0L);
|
||||
orders.put(joinRelation.getRight(), 1L);
|
||||
}
|
||||
}
|
||||
orders.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(d -> {
|
||||
linkDataSources.add(schema.getDatasource().get(d.getKey()));
|
||||
});
|
||||
}
|
||||
return linkDataSources;
|
||||
}
|
||||
|
||||
private static List<DataSource> getLinkDataSources(Set<String> baseIdentifiers,
|
||||
Set<String> queryDimension,
|
||||
List<String> measures,
|
||||
@@ -258,6 +329,12 @@ public class DataSourceNode extends SemanticNode {
|
||||
for (String linkName : linkDataSourceName) {
|
||||
linkDataSources.add(schema.getDatasource().get(linkName));
|
||||
}
|
||||
return linkDataSources;
|
||||
if (!CollectionUtils.isEmpty(linkDataSources)) {
|
||||
List<DataSource> all = new ArrayList<>();
|
||||
all.add(baseDataSource);
|
||||
all.addAll(linkDataSources);
|
||||
return all;
|
||||
}
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,24 +2,21 @@ package com.tencent.supersonic.semantic.query.parser.calcite.sql.node;
|
||||
|
||||
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.Configuration;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.sql.Optimization;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSqlDialect;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Collectors;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.sql.Optimization;
|
||||
import org.apache.calcite.jdbc.CalciteSchema;
|
||||
import org.apache.calcite.rel.RelNode;
|
||||
import org.apache.calcite.sql.JoinType;
|
||||
import org.apache.calcite.sql.SqlAsOperator;
|
||||
import org.apache.calcite.sql.SqlBasicCall;
|
||||
import org.apache.calcite.sql.SqlBinaryOperator;
|
||||
import org.apache.calcite.sql.SqlIdentifier;
|
||||
import org.apache.calcite.sql.SqlKind;
|
||||
import org.apache.calcite.sql.SqlLiteral;
|
||||
import org.apache.calcite.sql.SqlNode;
|
||||
import org.apache.calcite.sql.SqlSelect;
|
||||
import org.apache.calcite.sql.SqlWriterConfig;
|
||||
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
|
||||
import org.apache.calcite.sql.parser.SqlParseException;
|
||||
import org.apache.calcite.sql.parser.SqlParser;
|
||||
import org.apache.calcite.sql.parser.SqlParserPos;
|
||||
@@ -29,6 +26,15 @@ import org.apache.calcite.sql.validate.SqlValidatorScope;
|
||||
import org.apache.calcite.sql2rel.SqlToRelConverter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class SemanticNode {
|
||||
|
||||
public static SqlNode parse(String expression, SqlValidatorScope scope) throws Exception {
|
||||
@@ -130,6 +136,46 @@ public abstract class SemanticNode {
|
||||
sqlValidator.validate(SqlParser.create(sql, SqlParser.Config.DEFAULT).parseStmt()), false, true).rel;
|
||||
}
|
||||
|
||||
public static SqlBinaryOperator getBinaryOperator(String val) {
|
||||
if (val.equals("=")) {
|
||||
return SqlStdOperatorTable.EQUALS;
|
||||
}
|
||||
if (val.equals(">")) {
|
||||
return SqlStdOperatorTable.GREATER_THAN;
|
||||
}
|
||||
if (val.equals(">=")) {
|
||||
return SqlStdOperatorTable.GREATER_THAN_OR_EQUAL;
|
||||
}
|
||||
if (val.equals("<")) {
|
||||
return SqlStdOperatorTable.LESS_THAN;
|
||||
}
|
||||
if (val.equals("<=")) {
|
||||
return SqlStdOperatorTable.LESS_THAN_OR_EQUAL;
|
||||
}
|
||||
if (val.equals("!=")) {
|
||||
return SqlStdOperatorTable.NOT_EQUALS;
|
||||
}
|
||||
return SqlStdOperatorTable.EQUALS;
|
||||
}
|
||||
|
||||
public static SqlLiteral getJoinSqlLiteral(String joinType) {
|
||||
if (Objects.nonNull(joinType) && !joinType.isEmpty()) {
|
||||
if (joinType.toLowerCase().contains(JoinType.INNER.lowerName)) {
|
||||
return SqlLiteral.createSymbol(JoinType.INNER, SqlParserPos.ZERO);
|
||||
}
|
||||
if (joinType.toLowerCase().contains(JoinType.LEFT.lowerName)) {
|
||||
return SqlLiteral.createSymbol(JoinType.LEFT, SqlParserPos.ZERO);
|
||||
}
|
||||
if (joinType.toLowerCase().contains(JoinType.RIGHT.lowerName)) {
|
||||
return SqlLiteral.createSymbol(JoinType.RIGHT, SqlParserPos.ZERO);
|
||||
}
|
||||
if (joinType.toLowerCase().contains(JoinType.FULL.lowerName)) {
|
||||
return SqlLiteral.createSymbol(JoinType.FULL, SqlParserPos.ZERO);
|
||||
}
|
||||
}
|
||||
return SqlLiteral.createSymbol(JoinType.INNER, SqlParserPos.ZERO);
|
||||
}
|
||||
|
||||
public void accept(Optimization optimization) {
|
||||
optimization.visit(this);
|
||||
}
|
||||
|
||||
@@ -5,10 +5,9 @@ import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Constants;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.DataSource;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Dimension;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Identify;
|
||||
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Identify.Type;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.JoinRelation;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Materialization.TimePartType;
|
||||
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.s2sql.Metric;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.schema.SemanticSchema;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.sql.Renderer;
|
||||
@@ -19,6 +18,18 @@ import com.tencent.supersonic.semantic.query.parser.calcite.sql.node.FilterNode;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.sql.node.IdentifyNode;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.sql.node.MetricNode;
|
||||
import com.tencent.supersonic.semantic.query.parser.calcite.sql.node.SemanticNode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.calcite.sql.JoinConditionType;
|
||||
import org.apache.calcite.sql.SqlBasicCall;
|
||||
import org.apache.calcite.sql.SqlJoin;
|
||||
import org.apache.calcite.sql.SqlLiteral;
|
||||
import org.apache.calcite.sql.SqlNode;
|
||||
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
|
||||
import org.apache.calcite.sql.parser.SqlParserPos;
|
||||
import org.apache.calcite.sql.validate.SqlValidatorScope;
|
||||
import org.apache.commons.lang3.tuple.Triple;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -28,21 +39,11 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.calcite.sql.JoinConditionType;
|
||||
import org.apache.calcite.sql.JoinType;
|
||||
import org.apache.calcite.sql.SqlBasicCall;
|
||||
import org.apache.calcite.sql.SqlJoin;
|
||||
import org.apache.calcite.sql.SqlLiteral;
|
||||
import org.apache.calcite.sql.SqlNode;
|
||||
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
|
||||
import org.apache.calcite.sql.parser.SqlParserPos;
|
||||
import org.apache.calcite.sql.validate.SqlValidatorScope;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Slf4j
|
||||
public class JoinRender extends Renderer {
|
||||
@@ -51,7 +52,7 @@ public class JoinRender extends Renderer {
|
||||
public void render(MetricReq metricCommand, List<DataSource> dataSources, SqlValidatorScope scope,
|
||||
SemanticSchema schema, boolean nonAgg) throws Exception {
|
||||
String queryWhere = metricCommand.getWhere();
|
||||
dataSources = getOrderSource(dataSources);
|
||||
//dataSources = getOrderSource(dataSources);
|
||||
Set<String> whereFields = new HashSet<>();
|
||||
List<String> fieldWhere = new ArrayList<>();
|
||||
if (queryWhere != null && !queryWhere.isEmpty()) {
|
||||
@@ -68,6 +69,7 @@ public class JoinRender extends Renderer {
|
||||
TableView filterView = new TableView();
|
||||
Map<String, SqlNode> innerSelect = new HashMap<>();
|
||||
Set<String> filterDimension = new HashSet<>();
|
||||
Map<String, String> beforeSources = new HashMap<>();
|
||||
|
||||
for (int i = 0; i < dataSources.size(); i++) {
|
||||
final DataSource dataSource = dataSources.get(i);
|
||||
@@ -112,18 +114,12 @@ public class JoinRender extends Renderer {
|
||||
if (left == null) {
|
||||
leftTable = tableView;
|
||||
left = SemanticNode.buildAs(tableView.getAlias(), getTable(tableView, scope));
|
||||
beforeSources.put(dataSource.getName(), leftTable.getAlias());
|
||||
continue;
|
||||
}
|
||||
|
||||
left = new SqlJoin(
|
||||
SqlParserPos.ZERO,
|
||||
left,
|
||||
SqlLiteral.createBoolean(false, SqlParserPos.ZERO),
|
||||
SqlLiteral.createSymbol(JoinType.INNER, SqlParserPos.ZERO),
|
||||
SemanticNode.buildAs(tableView.getAlias(), getTable(tableView, scope)),
|
||||
SqlLiteral.createSymbol(JoinConditionType.ON, SqlParserPos.ZERO),
|
||||
getCondition(leftTable, tableView, dataSource, schema, scope));
|
||||
left = buildJoin(left, leftTable, tableView, beforeSources, dataSource, schema, scope);
|
||||
leftTable = tableView;
|
||||
beforeSources.put(dataSource.getName(), tableView.getAlias());
|
||||
}
|
||||
|
||||
for (Map.Entry<String, SqlNode> entry : innerSelect.entrySet()) {
|
||||
@@ -258,6 +254,76 @@ public class JoinRender extends Renderer {
|
||||
return SemanticNode.getTable(tableView.getTable());
|
||||
}
|
||||
|
||||
private SqlNode buildJoin(SqlNode left, TableView leftTable, TableView tableView, Map<String, String> before,
|
||||
DataSource dataSource,
|
||||
SemanticSchema schema, SqlValidatorScope scope)
|
||||
throws Exception {
|
||||
SqlNode condition = getCondition(leftTable, tableView, dataSource, schema, scope);
|
||||
SqlLiteral sqlLiteral = SemanticNode.getJoinSqlLiteral("");
|
||||
if (!TimePartType.ZIPPER.equals(leftTable.getDataSource().getTimePartType()) && !TimePartType.ZIPPER.equals(
|
||||
tableView.getDataSource().getTimePartType())) {
|
||||
JoinRelation matchJoinRelation = getMatchJoinRelation(before, tableView, schema);
|
||||
if (!CollectionUtils.isEmpty(matchJoinRelation.getJoinCondition())) {
|
||||
sqlLiteral = SemanticNode.getJoinSqlLiteral(matchJoinRelation.getJoinType());
|
||||
condition = getCondition(matchJoinRelation, scope);
|
||||
}
|
||||
}
|
||||
return new SqlJoin(
|
||||
SqlParserPos.ZERO,
|
||||
left,
|
||||
SqlLiteral.createBoolean(false, SqlParserPos.ZERO),
|
||||
sqlLiteral,
|
||||
SemanticNode.buildAs(tableView.getAlias(), getTable(tableView, scope)),
|
||||
SqlLiteral.createSymbol(JoinConditionType.ON, SqlParserPos.ZERO),
|
||||
condition
|
||||
);
|
||||
}
|
||||
|
||||
private JoinRelation getMatchJoinRelation(Map<String, String> before, TableView tableView, SemanticSchema schema) {
|
||||
JoinRelation matchJoinRelation = JoinRelation.builder().build();
|
||||
if (!CollectionUtils.isEmpty(schema.getJoinRelations())) {
|
||||
for (JoinRelation joinRelation : schema.getJoinRelations()) {
|
||||
if (joinRelation.getRight().equalsIgnoreCase(tableView.getDataSource().getName())
|
||||
&& before.containsKey(joinRelation.getLeft())) {
|
||||
matchJoinRelation.setJoinCondition(joinRelation.getJoinCondition().stream()
|
||||
.map(r -> Triple.of(before.get(joinRelation.getLeft()) + "." + r.getLeft(),
|
||||
r.getMiddle(), tableView.getAlias() + "." + r.getRight())).collect(
|
||||
Collectors.toList()));
|
||||
matchJoinRelation.setJoinType(joinRelation.getJoinType());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return matchJoinRelation;
|
||||
}
|
||||
|
||||
|
||||
private SqlNode getCondition(JoinRelation joinRelation,
|
||||
SqlValidatorScope scope) throws Exception {
|
||||
SqlNode condition = null;
|
||||
for (Triple<String, String, String> con : joinRelation.getJoinCondition()) {
|
||||
List<SqlNode> ons = new ArrayList<>();
|
||||
ons.add(SemanticNode.parse(con.getLeft(), scope));
|
||||
ons.add(SemanticNode.parse(con.getRight(), scope));
|
||||
if (Objects.isNull(condition)) {
|
||||
condition = new SqlBasicCall(
|
||||
SemanticNode.getBinaryOperator(con.getMiddle()),
|
||||
ons,
|
||||
SqlParserPos.ZERO, null);
|
||||
continue;
|
||||
}
|
||||
SqlNode addCondition = new SqlBasicCall(
|
||||
SemanticNode.getBinaryOperator(con.getMiddle()),
|
||||
ons,
|
||||
SqlParserPos.ZERO, null);
|
||||
condition = new SqlBasicCall(
|
||||
SqlStdOperatorTable.AND,
|
||||
new ArrayList<>(Arrays.asList(condition, addCondition)),
|
||||
SqlParserPos.ZERO, null);
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
private SqlNode getCondition(TableView left, TableView right, DataSource dataSource, SemanticSchema schema,
|
||||
SqlValidatorScope scope) throws Exception {
|
||||
if (TimePartType.ZIPPER.equals(left.getDataSource().getTimePartType()) || TimePartType.ZIPPER.equals(
|
||||
@@ -318,8 +384,7 @@ public class JoinRender extends Renderer {
|
||||
});
|
||||
int cnt = dataSources.size();
|
||||
List<Map.Entry<String, List<Identify>>> dataSourceIdentifyList = dataSourceIdentifies.entrySet().stream()
|
||||
.collect(
|
||||
Collectors.toList());
|
||||
.collect(Collectors.toList());
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
for (int j = i + 1; j < cnt; j++) {
|
||||
Set<String> primaries = IdentifyNode.getIdentifyNames(dataSourceIdentifyList.get(i).getValue(),
|
||||
@@ -384,6 +449,7 @@ public class JoinRender extends Renderer {
|
||||
orders.poll();
|
||||
visited.put(id, false);
|
||||
}
|
||||
|
||||
private void addZipperField(DataSource dataSource, List<String> fields) {
|
||||
if (TimePartType.ZIPPER.equals(dataSource.getTimePartType())) {
|
||||
dataSource.getDimensions().stream()
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.tencent.supersonic.common.pojo.Aggregator;
|
||||
import com.tencent.supersonic.common.pojo.Constants;
|
||||
import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.common.util.DateModeUtils;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatabaseResp;
|
||||
import com.tencent.supersonic.semantic.api.query.enums.AggOption;
|
||||
import com.tencent.supersonic.semantic.api.query.pojo.MetricTable;
|
||||
@@ -15,20 +16,20 @@ import com.tencent.supersonic.semantic.model.domain.Catalog;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.EngineTypeEnum;
|
||||
import com.tencent.supersonic.semantic.query.parser.SemanticConverter;
|
||||
import com.tencent.supersonic.semantic.query.service.SemanticQueryEngine;
|
||||
import com.tencent.supersonic.common.util.DateModeUtils;
|
||||
import com.tencent.supersonic.semantic.query.utils.QueryStructUtils;
|
||||
import com.tencent.supersonic.semantic.query.utils.SqlGenerateUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Component("CalculateAggConverter")
|
||||
@Slf4j
|
||||
@@ -66,7 +67,7 @@ public class CalculateAggConverter implements SemanticConverter {
|
||||
return generateRatioSqlCommand(queryStructCmd, engineTypeEnum, version);
|
||||
}
|
||||
ParseSqlReq sqlCommand = new ParseSqlReq();
|
||||
sqlCommand.setRootPath(catalog.getModelFullPath(queryStructCmd.getModelId()));
|
||||
sqlCommand.setRootPath(catalog.getModelFullPath(queryStructCmd.getModelIds()));
|
||||
String metricTableName = "v_metric_tb_tmp";
|
||||
MetricTable metricTable = new MetricTable();
|
||||
metricTable.setAlias(metricTableName);
|
||||
@@ -120,7 +121,7 @@ public class CalculateAggConverter implements SemanticConverter {
|
||||
@Override
|
||||
public void converter(Catalog catalog, QueryStructReq queryStructCmd, ParseSqlReq sqlCommend,
|
||||
MetricReq metricCommand) throws Exception {
|
||||
DatabaseResp databaseResp = catalog.getDatabaseByModelId(queryStructCmd.getModelId());
|
||||
DatabaseResp databaseResp = catalog.getDatabaseByModelId(queryStructCmd.getModelIds().get(0));
|
||||
ParseSqlReq parseSqlReq = generateSqlCommend(queryStructCmd,
|
||||
EngineTypeEnum.valueOf(databaseResp.getType().toUpperCase()), databaseResp.getVersion());
|
||||
sqlCommend.setSql(parseSqlReq.getSql());
|
||||
@@ -150,7 +151,7 @@ public class CalculateAggConverter implements SemanticConverter {
|
||||
throws Exception {
|
||||
check(queryStructCmd);
|
||||
ParseSqlReq sqlCommand = new ParseSqlReq();
|
||||
sqlCommand.setRootPath(catalog.getModelFullPath(queryStructCmd.getModelId()));
|
||||
sqlCommand.setRootPath(catalog.getModelFullPath(queryStructCmd.getModelIds()));
|
||||
String metricTableName = "v_metric_tb_tmp";
|
||||
MetricTable metricTable = new MetricTable();
|
||||
metricTable.setAlias(metricTableName);
|
||||
|
||||
@@ -26,7 +26,7 @@ public class DefaultDimValueConverter implements SemanticConverter {
|
||||
@Override
|
||||
public void converter(Catalog catalog, QueryStructReq queryStructCmd,
|
||||
ParseSqlReq sqlCommend, MetricReq metricCommand) throws Exception {
|
||||
List<DimensionResp> dimensionResps = catalog.getDimensions(queryStructCmd.getModelId());
|
||||
List<DimensionResp> dimensionResps = catalog.getDimensions(queryStructCmd.getModelIds());
|
||||
//dimension which has default values
|
||||
dimensionResps = dimensionResps.stream()
|
||||
.filter(dimensionResp -> !CollectionUtils.isEmpty(dimensionResp.getDefaultValues()))
|
||||
|
||||
@@ -33,9 +33,8 @@ public class MetricCheckConverter implements SemanticConverter {
|
||||
@Override
|
||||
public void converter(Catalog catalog, QueryStructReq queryStructReq, ParseSqlReq sqlCommend,
|
||||
MetricReq metricCommand) throws Exception {
|
||||
Long modelId = queryStructReq.getModelId();
|
||||
List<MetricResp> metricResps = catalog.getMetrics(modelId);
|
||||
List<DimensionResp> dimensionResps = catalog.getDimensions(modelId);
|
||||
List<MetricResp> metricResps = catalog.getMetrics(queryStructReq.getModelIds());
|
||||
List<DimensionResp> dimensionResps = catalog.getDimensions(queryStructReq.getModelIds());
|
||||
Map<Long, DimensionResp> dimensionMap = dimensionResps.stream()
|
||||
.collect(Collectors.toMap(DimensionResp::getId, d -> d));
|
||||
List<String> metricBizNames = queryStructReq.getMetrics();
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
package com.tencent.supersonic.semantic.query.parser.convert;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.tencent.supersonic.common.pojo.Aggregator;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Identify;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.Measure;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DatasourceResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.common.pojo.Filter;
|
||||
import com.tencent.supersonic.semantic.api.query.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.ParseSqlReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
|
||||
import com.tencent.supersonic.semantic.model.domain.Catalog;
|
||||
import com.tencent.supersonic.semantic.query.parser.SemanticConverter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Slf4j
|
||||
@Component("MultiSourceJoin")
|
||||
public class MultiSourceJoin implements SemanticConverter {
|
||||
|
||||
private final Catalog catalog;
|
||||
|
||||
|
||||
public MultiSourceJoin(Catalog catalog) {
|
||||
this.catalog = catalog;
|
||||
}
|
||||
|
||||
|
||||
public void buildJoinPrefix(QueryStructReq queryStructCmd) {
|
||||
List<String> groups = queryStructCmd.getGroups();
|
||||
List<Aggregator> aggregators = queryStructCmd.getAggregators();
|
||||
List<Filter> filters = queryStructCmd.getOriginalFilter();
|
||||
List<String> fields = Lists.newArrayList();
|
||||
fields.addAll(groups);
|
||||
fields.addAll(filters.stream().map(Filter::getBizName).collect(Collectors.toList()));
|
||||
|
||||
if (CollectionUtils.isEmpty(groups) || CollectionUtils.isEmpty(aggregators)) {
|
||||
return;
|
||||
}
|
||||
Long modelId = queryStructCmd.getModelId();
|
||||
List<String> aggs = aggregators.stream().map(Aggregator::getColumn).collect(Collectors.toList());
|
||||
Map<String, DimensionResp> dimensionMap = catalog.getDimensions(modelId).stream()
|
||||
.filter(dimensionDesc -> fields.contains(dimensionDesc.getBizName()))
|
||||
.collect(Collectors.toMap(DimensionResp::getBizName, dimensionDesc -> dimensionDesc));
|
||||
List<MetricResp> metricDescList = catalog.getMetrics(modelId).stream()
|
||||
.filter(metricDesc -> aggs.contains(metricDesc.getBizName()))
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, DatasourceResp> datasourceMap = catalog.getDatasourceList(modelId)
|
||||
.stream().collect(Collectors.toMap(DatasourceResp::getId, datasource -> datasource));
|
||||
//check groups filters and aggs is in same datasource
|
||||
if (!isInSameDatasource(new ArrayList<>(dimensionMap.values()), metricDescList)) {
|
||||
List<String> groupsWithPrefix = Lists.newArrayList();
|
||||
for (String group : groups) {
|
||||
DimensionResp dimensionDesc = dimensionMap.get(group);
|
||||
if (dimensionDesc == null) {
|
||||
groupsWithPrefix.add(group);
|
||||
continue;
|
||||
}
|
||||
String joinKeyName = getJoinKey(datasourceMap, dimensionDesc.getDatasourceId());
|
||||
if (joinKeyName.equalsIgnoreCase(group)) {
|
||||
groupsWithPrefix.add(group);
|
||||
} else {
|
||||
String groupWithPrefix = String.format("%s__%s", joinKeyName, group);
|
||||
groupsWithPrefix.add(groupWithPrefix);
|
||||
}
|
||||
}
|
||||
List<Filter> filtersWithPrefix = Lists.newArrayList();
|
||||
for (Filter filter : filters) {
|
||||
DimensionResp dimensionDesc = dimensionMap.get(filter.getBizName());
|
||||
if (dimensionDesc == null) {
|
||||
filtersWithPrefix.add(filter);
|
||||
continue;
|
||||
}
|
||||
String joinKeyName = getJoinKey(datasourceMap, dimensionDesc.getDatasourceId());
|
||||
if (joinKeyName.equalsIgnoreCase(filter.getBizName())) {
|
||||
filtersWithPrefix.add(filter);
|
||||
} else {
|
||||
String filterWithPrefix = String.format("%s__%s", joinKeyName, filter.getBizName());
|
||||
filter.setBizName(filterWithPrefix);
|
||||
filtersWithPrefix.add(filter);
|
||||
}
|
||||
}
|
||||
queryStructCmd.setGroups(groupsWithPrefix);
|
||||
queryStructCmd.setDimensionFilters(filtersWithPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String getJoinKey(Map<Long, DatasourceResp> datasourceMap, Long datasourceId) {
|
||||
DatasourceResp datasourceDesc = datasourceMap.get(datasourceId);
|
||||
List<Identify> identifies = datasourceDesc.getDatasourceDetail().getIdentifiers();
|
||||
|
||||
Optional<Identify> identifyOptional = identifies.stream()
|
||||
.filter(identify -> identify.getType().equalsIgnoreCase("primary")).findFirst();
|
||||
if (identifyOptional.isPresent()) {
|
||||
return identifyOptional.get().getBizName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
private boolean isInSameDatasource(List<DimensionResp> dimensionDescs, List<MetricResp> metricDescs) {
|
||||
Set<Long> datasourceIdSet = Sets.newHashSet();
|
||||
datasourceIdSet.addAll(dimensionDescs.stream().map(DimensionResp::getDatasourceId).filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet()));
|
||||
datasourceIdSet.addAll(
|
||||
metricDescs.stream().flatMap(metricDesc -> metricDesc.getTypeParams().getMeasures().stream())
|
||||
.map(Measure::getDatasourceId).filter(Objects::nonNull).collect(Collectors.toList()));
|
||||
log.info("[multi source join] datasource id:{}", datasourceIdSet);
|
||||
return datasourceIdSet.size() <= 1;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(QueryStructReq queryStructCmd) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void converter(Catalog catalog, QueryStructReq queryStructCmd, ParseSqlReq sqlCommend,
|
||||
MetricReq metricCommand) throws Exception {
|
||||
buildJoinPrefix(queryStructCmd);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ import org.springframework.util.CollectionUtils;
|
||||
public class ParserDefaultConverter implements SemanticConverter {
|
||||
|
||||
|
||||
|
||||
private final CalculateAggConverter calculateCoverterAgg;
|
||||
private final QueryStructUtils queryStructUtils;
|
||||
|
||||
@@ -57,20 +56,21 @@ public class ParserDefaultConverter implements SemanticConverter {
|
||||
sqlCommend.setVariables(queryStructCmd.getParams().stream()
|
||||
.collect(Collectors.toMap(Param::getName, Param::getValue, (k1, k2) -> k1)));
|
||||
sqlCommend.setLimit(queryStructCmd.getLimit());
|
||||
String rootPath = catalog.getModelFullPath(queryStructCmd.getModelId());
|
||||
String rootPath = catalog.getModelFullPath(queryStructCmd.getModelIds());
|
||||
sqlCommend.setRootPath(rootPath);
|
||||
|
||||
// todo tmp delete
|
||||
// support detail query
|
||||
if (queryStructCmd.getQueryType().isNativeAggQuery() && CollectionUtils.isEmpty(sqlCommend.getMetrics())) {
|
||||
String internalMetricName = queryStructUtils.generateInternalMetricName(
|
||||
queryStructCmd.getModelId(), queryStructCmd.getGroups());
|
||||
sqlCommend.getMetrics().add(internalMetricName);
|
||||
for (Long modelId : queryStructCmd.getModelIds()) {
|
||||
String internalMetricName = queryStructUtils.generateInternalMetricName(
|
||||
modelId, queryStructCmd.getGroups());
|
||||
sqlCommend.getMetrics().add(internalMetricName);
|
||||
}
|
||||
}
|
||||
|
||||
return sqlCommend;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -26,15 +26,6 @@ import com.tencent.supersonic.semantic.model.domain.pojo.EngineTypeEnum;
|
||||
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
|
||||
import com.tencent.supersonic.semantic.query.service.SemanticQueryEngine;
|
||||
import com.tencent.supersonic.semantic.query.utils.QueryStructUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -43,6 +34,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class QueryReqConverter {
|
||||
@@ -57,13 +57,13 @@ public class QueryReqConverter {
|
||||
@Autowired
|
||||
private Catalog catalog;
|
||||
|
||||
public QueryStatement convert(QueryS2SQLReq databaseReq, ModelSchemaResp modelSchemaResp) throws Exception {
|
||||
public QueryStatement convert(QueryS2SQLReq databaseReq, List<ModelSchemaResp> modelSchemaResps) throws Exception {
|
||||
|
||||
if (Objects.isNull(modelSchemaResp)) {
|
||||
if (CollectionUtils.isEmpty(modelSchemaResps)) {
|
||||
return new QueryStatement();
|
||||
}
|
||||
//1.convert name to bizName
|
||||
convertNameToBizName(databaseReq, modelSchemaResp);
|
||||
convertNameToBizName(databaseReq, modelSchemaResps);
|
||||
//2.functionName corrector
|
||||
functionNameCorrector(databaseReq);
|
||||
//3.correct tableName
|
||||
@@ -75,21 +75,23 @@ public class QueryReqConverter {
|
||||
}
|
||||
//4.build MetricTables
|
||||
List<String> allFields = SqlParserSelectHelper.getAllFields(databaseReq.getSql());
|
||||
List<String> metrics = getMetrics(modelSchemaResp, allFields);
|
||||
List<String> metrics = getMetrics(modelSchemaResps, allFields);
|
||||
QueryStructReq queryStructCmd = new QueryStructReq();
|
||||
MetricTable metricTable = new MetricTable();
|
||||
metricTable.setMetrics(metrics);
|
||||
|
||||
Set<String> dimensions = getDimensions(modelSchemaResp, allFields);
|
||||
Set<String> dimensions = getDimensions(modelSchemaResps, allFields);
|
||||
|
||||
metricTable.setDimensions(new ArrayList<>(dimensions));
|
||||
|
||||
metricTable.setAlias(tableName.toLowerCase());
|
||||
// if metric empty , fill model default
|
||||
if (CollectionUtils.isEmpty(metricTable.getMetrics())) {
|
||||
metricTable.setMetrics(new ArrayList<>(Arrays.asList(
|
||||
queryStructUtils.generateInternalMetricName(databaseReq.getModelId(),
|
||||
metricTable.getDimensions()))));
|
||||
metricTable.setMetrics(new ArrayList<>());
|
||||
for (Long modelId : databaseReq.getModelIds()) {
|
||||
metricTable.getMetrics().add(queryStructUtils.generateInternalMetricName(modelId,
|
||||
metricTable.getDimensions()));
|
||||
}
|
||||
} else {
|
||||
queryStructCmd.setAggregators(
|
||||
metricTable.getMetrics().stream().map(m -> new Aggregator(m, AggOperatorEnum.UNKNOWN)).collect(
|
||||
@@ -102,9 +104,10 @@ public class QueryReqConverter {
|
||||
//4.build ParseSqlReq
|
||||
ParseSqlReq result = new ParseSqlReq();
|
||||
BeanUtils.copyProperties(databaseReq, result);
|
||||
result.setRootPath(domainService.getModelFullPathMap().get(databaseReq.getModelId()));
|
||||
|
||||
result.setRootPath(catalog.getModelFullPath(databaseReq.getModelIds()));
|
||||
result.setTables(tables);
|
||||
DatabaseResp database = catalog.getDatabaseByModelId(databaseReq.getModelId());
|
||||
DatabaseResp database = catalog.getDatabaseByModelId(databaseReq.getModelIds().get(0));
|
||||
if (!queryStructUtils.isSupportWith(EngineTypeEnum.valueOf(database.getType().toUpperCase()),
|
||||
database.getVersion())) {
|
||||
result.setSupportWith(false);
|
||||
@@ -112,7 +115,7 @@ public class QueryReqConverter {
|
||||
}
|
||||
//5.physicalSql by ParseSqlReq
|
||||
queryStructCmd.setDateInfo(queryStructUtils.getDateConfBySql(databaseReq.getSql()));
|
||||
queryStructCmd.setModelId(databaseReq.getModelId());
|
||||
queryStructCmd.setModelIds(databaseReq.getModelIds().stream().collect(Collectors.toSet()));
|
||||
queryStructCmd.setQueryType(getQueryType(aggOption));
|
||||
log.info("QueryReqConverter queryStructCmd[{}]", queryStructCmd);
|
||||
QueryStatement queryStatement = parserService.physicalSql(queryStructCmd, result);
|
||||
@@ -132,8 +135,8 @@ public class QueryReqConverter {
|
||||
return AggOption.DEFAULT;
|
||||
}
|
||||
|
||||
private void convertNameToBizName(QueryS2SQLReq databaseReq, ModelSchemaResp modelSchemaResp) {
|
||||
Map<String, String> fieldNameToBizNameMap = getFieldNameToBizNameMap(modelSchemaResp);
|
||||
private void convertNameToBizName(QueryS2SQLReq databaseReq, List<ModelSchemaResp> modelSchemaResps) {
|
||||
Map<String, String> fieldNameToBizNameMap = getFieldNameToBizNameMap(modelSchemaResps);
|
||||
String sql = databaseReq.getSql();
|
||||
log.info("convert name to bizName before:{}", sql);
|
||||
String replaceFields = SqlParserReplaceHelper.replaceFields(sql, fieldNameToBizNameMap, true);
|
||||
@@ -141,26 +144,28 @@ public class QueryReqConverter {
|
||||
databaseReq.setSql(replaceFields);
|
||||
}
|
||||
|
||||
private Set<String> getDimensions(ModelSchemaResp modelSchemaResp, List<String> allFields) {
|
||||
Map<String, String> dimensionLowerToNameMap = modelSchemaResp.getDimensions().stream()
|
||||
.collect(Collectors.toMap(entry -> entry.getBizName().toLowerCase(), entry -> entry.getBizName()));
|
||||
private Set<String> getDimensions(List<ModelSchemaResp> modelSchemaResps, List<String> allFields) {
|
||||
Map<String, String> dimensionLowerToNameMap = modelSchemaResps.stream().flatMap(modelSchemaResp
|
||||
-> modelSchemaResp.getDimensions().stream())
|
||||
.collect(Collectors.toMap(entry -> entry.getBizName().toLowerCase(), SchemaItem::getBizName));
|
||||
Map<String, String> internalLowerToNameMap = QueryStructUtils.internalCols.stream()
|
||||
.collect(Collectors.toMap(a -> a.toLowerCase(), a -> a));
|
||||
.collect(Collectors.toMap(String::toLowerCase, a -> a));
|
||||
dimensionLowerToNameMap.putAll(internalLowerToNameMap);
|
||||
return allFields.stream()
|
||||
.filter(entry -> dimensionLowerToNameMap.containsKey(entry.toLowerCase()))
|
||||
.map(entry -> dimensionLowerToNameMap.get(entry.toLowerCase())).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private List<String> getMetrics(ModelSchemaResp modelSchemaResp, List<String> allFields) {
|
||||
Map<String, String> metricLowerToNameMap = modelSchemaResp.getMetrics().stream()
|
||||
.collect(Collectors.toMap(entry -> entry.getBizName().toLowerCase(), entry -> entry.getBizName()));
|
||||
private List<String> getMetrics(List<ModelSchemaResp> modelSchemaResps, List<String> allFields) {
|
||||
Map<String, String> metricLowerToNameMap = modelSchemaResps.stream()
|
||||
.flatMap(modelSchemaResp -> modelSchemaResp.getMetrics().stream())
|
||||
.collect(Collectors.toMap(entry -> entry.getBizName().toLowerCase(), SchemaItem::getBizName));
|
||||
return allFields.stream().filter(entry -> metricLowerToNameMap.containsKey(entry.toLowerCase()))
|
||||
.map(entry -> metricLowerToNameMap.get(entry.toLowerCase())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void functionNameCorrector(QueryS2SQLReq databaseReq) {
|
||||
DatabaseResp database = catalog.getDatabaseByModelId(databaseReq.getModelId());
|
||||
DatabaseResp database = catalog.getDatabaseByModelId(databaseReq.getModelIds().get(0));
|
||||
if (Objects.isNull(database) || Objects.isNull(database.getType())) {
|
||||
return;
|
||||
}
|
||||
@@ -174,16 +179,17 @@ public class QueryReqConverter {
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, String> getFieldNameToBizNameMap(ModelSchemaResp modelSchemaResp) {
|
||||
protected Map<String, String> getFieldNameToBizNameMap(List<ModelSchemaResp> modelSchemaResps) {
|
||||
// support fieldName and field alias to bizName
|
||||
Map<String, String> dimensionResults = modelSchemaResp.getDimensions().stream()
|
||||
Map<String, String> dimensionResults = modelSchemaResps.stream().flatMap(modelSchemaResp
|
||||
-> modelSchemaResp.getDimensions().stream())
|
||||
.flatMap(entry -> getPairStream(entry.getAlias(), entry.getName(), entry.getBizName()))
|
||||
.collect(Collectors.toMap(a -> a.getLeft(), a -> a.getRight(), (k1, k2) -> k1));
|
||||
.collect(Collectors.toMap(Pair::getLeft, Pair::getRight, (k1, k2) -> k1));
|
||||
|
||||
Map<String, String> metricResults = modelSchemaResp.getMetrics().stream()
|
||||
Map<String, String> metricResults = modelSchemaResps.stream().flatMap(modelSchemaResp
|
||||
-> modelSchemaResp.getMetrics().stream())
|
||||
.flatMap(entry -> getPairStream(entry.getAlias(), entry.getName(), entry.getBizName()))
|
||||
.collect(Collectors.toMap(a -> a.getLeft(), a -> a.getRight(), (k1, k2) -> k1));
|
||||
|
||||
.collect(Collectors.toMap(Pair::getLeft, Pair::getRight, (k1, k2) -> k1));
|
||||
|
||||
dimensionResults.putAll(TimeDimensionEnum.getChNameToNameMap());
|
||||
dimensionResults.putAll(TimeDimensionEnum.getNameToNameMap());
|
||||
@@ -204,8 +210,10 @@ public class QueryReqConverter {
|
||||
}
|
||||
|
||||
public void correctTableName(QueryS2SQLReq databaseReq) {
|
||||
String sql = SqlParserReplaceHelper.replaceTable(databaseReq.getSql(),
|
||||
Constants.TABLE_PREFIX + databaseReq.getModelId());
|
||||
String sql = databaseReq.getSql();
|
||||
for (Long modelId : databaseReq.getModelIds()) {
|
||||
sql = SqlParserReplaceHelper.replaceTable(sql, Constants.TABLE_PREFIX + modelId);
|
||||
}
|
||||
databaseReq.setSql(sql);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,15 @@ package com.tencent.supersonic.semantic.query.persistence.pojo;
|
||||
|
||||
import com.tencent.supersonic.semantic.api.query.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.ParseSqlReq;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class QueryStatement {
|
||||
|
||||
private Long modelId = 0L;
|
||||
private List<Long> modelIds;
|
||||
private String sql = "";
|
||||
private String sourceId = "";
|
||||
private String errMsg = "";
|
||||
|
||||
@@ -9,23 +9,24 @@ import com.tencent.supersonic.semantic.api.materialization.response.Materializat
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.PageDimensionReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.PageMetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
import com.tencent.supersonic.semantic.query.service.MaterializationService;
|
||||
import com.tencent.supersonic.semantic.query.service.SchemaService;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/semantic/schema")
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.tencent.supersonic.semantic.query.service;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRes;
|
||||
import com.tencent.supersonic.auth.api.authorization.pojo.AuthResGrp;
|
||||
@@ -16,7 +16,6 @@ import com.tencent.supersonic.common.pojo.QueryColumn;
|
||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.common.pojo.enums.SensitiveLevelEnum;
|
||||
import com.tencent.supersonic.common.pojo.exception.InvalidPermissionException;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
@@ -26,20 +25,18 @@ import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.assertj.core.util.Sets;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@@ -57,64 +54,62 @@ public class AuthCommonService {
|
||||
@Autowired
|
||||
private ModelService modelService;
|
||||
|
||||
public boolean doModelAdmin(User user, Long modelId) {
|
||||
public boolean doModelAdmin(User user, List<Long> modelIds) {
|
||||
List<ModelResp> modelListAdmin = modelService.getModelListWithAuth(user, null, AuthType.ADMIN);
|
||||
if (CollectionUtils.isEmpty(modelListAdmin)) {
|
||||
return false;
|
||||
} else {
|
||||
Map<Long, List<ModelResp>> id2modelResp = modelListAdmin.stream()
|
||||
.collect(Collectors.groupingBy(SchemaItem::getId));
|
||||
return !CollectionUtils.isEmpty(id2modelResp) && id2modelResp.containsKey(modelId);
|
||||
Set<Long> modelAdmins = modelListAdmin.stream().map(ModelResp::getId).collect(Collectors.toSet());
|
||||
return !CollectionUtils.isEmpty(modelAdmins) && modelAdmins.containsAll(modelIds);
|
||||
}
|
||||
}
|
||||
|
||||
public void doModelVisible(User user, Long modelId) {
|
||||
public void doModelVisible(User user, List<Long> modelIds) {
|
||||
Boolean visible = true;
|
||||
List<ModelResp> modelListVisible = modelService.getModelListWithAuth(user, null, AuthType.VISIBLE);
|
||||
if (CollectionUtils.isEmpty(modelListVisible)) {
|
||||
visible = false;
|
||||
} else {
|
||||
Map<Long, List<ModelResp>> id2domainDesc = modelListVisible.stream()
|
||||
.collect(Collectors.groupingBy(SchemaItem::getId));
|
||||
if (!CollectionUtils.isEmpty(id2domainDesc) && !id2domainDesc.containsKey(modelId)) {
|
||||
Set<Long> modelVisibles = modelListVisible.stream().map(ModelResp::getId).collect(Collectors.toSet());
|
||||
if (!CollectionUtils.isEmpty(modelVisibles) && !modelVisibles.containsAll(modelIds)) {
|
||||
visible = false;
|
||||
}
|
||||
}
|
||||
if (!visible) {
|
||||
ModelResp modelResp = modelService.getModel(modelId);
|
||||
ModelResp modelResp = modelService.getModel(modelIds.get(0));
|
||||
String modelName = modelResp.getName();
|
||||
List<String> admins = modelService.getModelAdmin(modelResp.getId());
|
||||
String message = String.format("您没有主题域[%s]权限,请联系管理员%s开通", modelName, admins);
|
||||
String message = String.format("您没有模型[%s]权限,请联系管理员%s开通", modelName, admins);
|
||||
throw new InvalidPermissionException(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Set<String> getHighSensitiveColsByModelId(Long modelId) {
|
||||
public Set<String> getHighSensitiveColsByModelId(List<Long> modelIds) {
|
||||
Set<String> highSensitiveCols = new HashSet<>();
|
||||
MetaFilter metaFilter = new MetaFilter();
|
||||
metaFilter.setModelIds(Lists.newArrayList(modelId));
|
||||
metaFilter.setModelIds(modelIds);
|
||||
metaFilter.setSensitiveLevel(SensitiveLevelEnum.HIGH.getCode());
|
||||
List<DimensionResp> highSensitiveDimensions = dimensionService.getDimensions(metaFilter);
|
||||
List<MetricResp> highSensitiveMetrics = metricService.getMetrics(metaFilter);
|
||||
if (!CollectionUtils.isEmpty(highSensitiveDimensions)) {
|
||||
highSensitiveDimensions.stream().forEach(dim -> highSensitiveCols.add(dim.getBizName()));
|
||||
highSensitiveDimensions.forEach(dim -> highSensitiveCols.add(dim.getBizName()));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(highSensitiveMetrics)) {
|
||||
highSensitiveMetrics.stream().forEach(metric -> highSensitiveCols.add(metric.getBizName()));
|
||||
highSensitiveMetrics.forEach(metric -> highSensitiveCols.add(metric.getBizName()));
|
||||
}
|
||||
return highSensitiveCols;
|
||||
}
|
||||
|
||||
public AuthorizedResourceResp getAuthorizedResource(User user, Long modelId,
|
||||
public AuthorizedResourceResp getAuthorizedResource(User user, List<Long> modelIds,
|
||||
Set<String> sensitiveResReq) {
|
||||
List<AuthRes> resourceReqList = new ArrayList<>();
|
||||
sensitiveResReq.forEach(res -> resourceReqList.add(new AuthRes(modelId, res)));
|
||||
sensitiveResReq.forEach(res -> resourceReqList.add(new AuthRes(modelIds.get(0), res)));
|
||||
QueryAuthResReq queryAuthResReq = new QueryAuthResReq();
|
||||
queryAuthResReq.setResources(resourceReqList);
|
||||
queryAuthResReq.setModelId(modelId);
|
||||
queryAuthResReq.setModelIds(modelIds);
|
||||
AuthorizedResourceResp authorizedResource = fetchAuthRes(queryAuthResReq, user);
|
||||
log.info("user:{}, domainId:{}, after queryAuthorizedResources:{}", user.getName(), modelId,
|
||||
log.info("user:{}, domainId:{}, after queryAuthorizedResources:{}", user.getName(), modelIds,
|
||||
authorizedResource);
|
||||
return authorizedResource;
|
||||
}
|
||||
@@ -124,13 +119,13 @@ public class AuthCommonService {
|
||||
return authService.queryAuthorizedResources(queryAuthResReq, user);
|
||||
}
|
||||
|
||||
public Set<String> getAuthResNameSet(AuthorizedResourceResp authorizedResource, Long modelId) {
|
||||
public Set<String> getAuthResNameSet(AuthorizedResourceResp authorizedResource, List<Long> modelIds) {
|
||||
Set<String> resAuthName = new HashSet<>();
|
||||
List<AuthResGrp> authResGrpList = authorizedResource.getResources();
|
||||
authResGrpList.stream().forEach(authResGrp -> {
|
||||
List<AuthRes> cols = authResGrp.getGroup();
|
||||
if (!CollectionUtils.isEmpty(cols)) {
|
||||
cols.stream().filter(col -> modelId.equals(col.getModelId()))
|
||||
cols.stream().filter(col -> modelIds.contains(col.getModelId()))
|
||||
.forEach(col -> resAuthName.add(col.getName()));
|
||||
}
|
||||
|
||||
@@ -148,8 +143,9 @@ public class AuthCommonService {
|
||||
}
|
||||
|
||||
public QueryResultWithSchemaResp getQueryResultWithColumns(QueryResultWithSchemaResp resultWithColumns,
|
||||
Long domainId, AuthorizedResourceResp authResource) {
|
||||
addPromptInfoInfo(domainId, resultWithColumns, authResource, Sets.newHashSet());
|
||||
List<Long> modelIds,
|
||||
AuthorizedResourceResp authResource) {
|
||||
addPromptInfoInfo(modelIds, resultWithColumns, authResource, Sets.newHashSet());
|
||||
return resultWithColumns;
|
||||
}
|
||||
|
||||
@@ -245,20 +241,20 @@ public class AuthCommonService {
|
||||
return queryResultWithColumns;
|
||||
}
|
||||
|
||||
public void addPromptInfoInfo(Long modelId, QueryResultWithSchemaResp queryResultWithColumns,
|
||||
public void addPromptInfoInfo(List<Long> modelIds, QueryResultWithSchemaResp queryResultWithColumns,
|
||||
AuthorizedResourceResp authorizedResource, Set<String> need2Apply) {
|
||||
List<DimensionFilter> filters = authorizedResource.getFilters();
|
||||
if (CollectionUtils.isEmpty(need2Apply) && CollectionUtils.isEmpty(filters)) {
|
||||
return;
|
||||
}
|
||||
List<String> admins = modelService.getModelAdmin(modelId);
|
||||
List<String> admins = modelService.getModelAdmin(modelIds.get(0));
|
||||
if (!CollectionUtils.isEmpty(need2Apply)) {
|
||||
String promptInfo = String.format("当前结果已经过脱敏处理, 申请权限请联系管理员%s", admins);
|
||||
queryResultWithColumns.setQueryAuthorization(new QueryAuthorization(promptInfo));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(filters)) {
|
||||
log.debug("dimensionFilters:{}", filters);
|
||||
ModelResp modelResp = modelService.getModel(modelId);
|
||||
ModelResp modelResp = modelService.getModel(modelIds.get(0));
|
||||
List<String> exprList = new ArrayList<>();
|
||||
List<String> descList = new ArrayList<>();
|
||||
filters.stream().forEach(filter -> {
|
||||
|
||||
@@ -12,10 +12,13 @@ import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.query.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.materialization.domain.MaterializationConfService;
|
||||
import com.tencent.supersonic.semantic.model.domain.Catalog;
|
||||
import com.tencent.supersonic.semantic.model.domain.DatasourceService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
|
||||
import com.tencent.supersonic.semantic.query.utils.QueryStructUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
@@ -24,9 +27,6 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Service("MaterializationService")
|
||||
@Slf4j
|
||||
@@ -34,19 +34,17 @@ public class MaterializationServiceImpl implements MaterializationService {
|
||||
|
||||
protected final MaterializationConfService materializationConfService;
|
||||
protected final ModelService modelService;
|
||||
protected final DatasourceService datasourceService;
|
||||
protected final Catalog catalog;
|
||||
protected final QueryStructUtils queryStructUtils;
|
||||
protected final QueryService queryService;
|
||||
|
||||
public MaterializationServiceImpl(
|
||||
MaterializationConfService materializationConfService,
|
||||
ModelService modelService, DatasourceService datasourceService,
|
||||
ModelService modelService,
|
||||
Catalog catalog, QueryStructUtils queryStructUtils,
|
||||
QueryService queryService) {
|
||||
this.materializationConfService = materializationConfService;
|
||||
this.modelService = modelService;
|
||||
this.datasourceService = datasourceService;
|
||||
this.catalog = catalog;
|
||||
this.queryStructUtils = queryStructUtils;
|
||||
this.queryService = queryService;
|
||||
@@ -72,11 +70,12 @@ public class MaterializationServiceImpl implements MaterializationService {
|
||||
ModelSchemaFilterReq modelFilter = new ModelSchemaFilterReq();
|
||||
modelFilter.setModelIds(Arrays.asList(materializationSourceResp.getModelId()));
|
||||
List<ModelSchemaResp> modelSchemaRespList = modelService.fetchModelSchema(modelFilter);
|
||||
List<MeasureResp> measureRespList = datasourceService.getMeasureListOfModel(
|
||||
//todo
|
||||
List<MeasureResp> measureRespList = modelService.getMeasureListOfModel(
|
||||
Lists.newArrayList(materializationSourceResp.getModelId()));
|
||||
modelSchemaRespList.stream().forEach(m -> {
|
||||
m.getDimensions().stream()
|
||||
.filter(mm -> mm.getDatasourceId().equals(materializationSourceReq.getDataSourceId())
|
||||
.filter(mm -> mm.getModelId().equals(materializationSourceReq.getDataSourceId())
|
||||
&& materializationSourceResp.getDimensions().keySet().contains(mm.getId())
|
||||
).forEach(mm -> {
|
||||
dimensionFields.add(mm.getBizName());
|
||||
|
||||
@@ -4,42 +4,43 @@ import com.google.common.cache.CacheBuilder;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.Aggregator;
|
||||
import com.tencent.supersonic.common.pojo.DateConf;
|
||||
import com.tencent.supersonic.common.pojo.Filter;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.common.util.cache.CacheUtils;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.QueryTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ExplainResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import com.tencent.supersonic.semantic.api.query.pojo.Cache;
|
||||
import com.tencent.supersonic.common.pojo.Filter;
|
||||
import com.tencent.supersonic.semantic.api.query.request.ExplainSqlReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.ItemUseReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.MetricReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryDimValueReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryS2SQLReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryMultiStructReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryS2SQLReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
|
||||
import com.tencent.supersonic.semantic.api.query.response.ItemUseResp;
|
||||
import com.tencent.supersonic.semantic.query.utils.S2SQLPermissionAnnotation;
|
||||
import com.tencent.supersonic.semantic.query.executor.QueryExecutor;
|
||||
import com.tencent.supersonic.semantic.query.parser.convert.QueryReqConverter;
|
||||
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
|
||||
import com.tencent.supersonic.semantic.query.utils.QueryUtils;
|
||||
import com.tencent.supersonic.semantic.query.utils.S2SQLPermissionAnnotation;
|
||||
import com.tencent.supersonic.semantic.query.utils.StatUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Service
|
||||
@@ -75,11 +76,11 @@ public class QueryServiceImpl implements QueryService {
|
||||
@Override
|
||||
@S2SQLPermissionAnnotation
|
||||
@SneakyThrows
|
||||
public Object queryBySql(QueryS2SQLReq querySqlCmd, User user) {
|
||||
statUtils.initStatInfo(querySqlCmd, user);
|
||||
public Object queryBySql(QueryS2SQLReq queryS2SQLReq, User user) {
|
||||
statUtils.initStatInfo(queryS2SQLReq, user);
|
||||
QueryStatement queryStatement = new QueryStatement();
|
||||
try {
|
||||
queryStatement = convertToQueryStatement(querySqlCmd, user);
|
||||
queryStatement = convertToQueryStatement(queryS2SQLReq, user);
|
||||
} catch (Exception e) {
|
||||
log.info("convertToQueryStatement has a exception:{}", e.toString());
|
||||
}
|
||||
@@ -95,18 +96,11 @@ public class QueryServiceImpl implements QueryService {
|
||||
|
||||
private QueryStatement convertToQueryStatement(QueryS2SQLReq querySqlCmd, User user) throws Exception {
|
||||
ModelSchemaFilterReq filter = new ModelSchemaFilterReq();
|
||||
List<Long> modelIds = new ArrayList<>();
|
||||
modelIds.add(querySqlCmd.getModelId());
|
||||
|
||||
filter.setModelIds(modelIds);
|
||||
filter.setModelIds(querySqlCmd.getModelIds());
|
||||
SchemaService schemaService = ContextUtils.getBean(SchemaService.class);
|
||||
List<ModelSchemaResp> domainSchemas = schemaService.fetchModelSchema(filter, user);
|
||||
ModelSchemaResp domainSchema = null;
|
||||
if (CollectionUtils.isNotEmpty(domainSchemas)) {
|
||||
domainSchema = domainSchemas.get(0);
|
||||
}
|
||||
QueryStatement queryStatement = queryReqConverter.convert(querySqlCmd, domainSchema);
|
||||
queryStatement.setModelId(querySqlCmd.getModelId());
|
||||
List<ModelSchemaResp> modelSchemaResps = schemaService.fetchModelSchema(filter, user);
|
||||
QueryStatement queryStatement = queryReqConverter.convert(querySqlCmd, modelSchemaResps);
|
||||
queryStatement.setModelIds(querySqlCmd.getModelIds());
|
||||
return queryStatement;
|
||||
}
|
||||
|
||||
@@ -116,7 +110,7 @@ public class QueryServiceImpl implements QueryService {
|
||||
log.info("[queryStructCmd:{}]", queryStructCmd);
|
||||
try {
|
||||
statUtils.initStatInfo(queryStructCmd, user);
|
||||
String cacheKey = cacheUtils.generateCacheKey(queryStructCmd.getModelId().toString(),
|
||||
String cacheKey = cacheUtils.generateCacheKey(getKeyByModelIds(queryStructCmd.getModelIds()),
|
||||
queryStructCmd.generateCommandMd5());
|
||||
handleGlobalCacheDisable(queryStructCmd);
|
||||
boolean isCache = isCache(queryStructCmd);
|
||||
@@ -160,7 +154,7 @@ public class QueryServiceImpl implements QueryService {
|
||||
throws Exception {
|
||||
statUtils.initStatInfo(queryMultiStructReq.getQueryStructReqs().get(0), user);
|
||||
String cacheKey = cacheUtils.generateCacheKey(
|
||||
queryMultiStructReq.getQueryStructReqs().get(0).getModelId().toString(),
|
||||
getKeyByModelIds(queryMultiStructReq.getQueryStructReqs().get(0).getModelIds()),
|
||||
queryMultiStructReq.generateCommandMd5());
|
||||
boolean isCache = isCache(queryMultiStructReq);
|
||||
QueryResultWithSchemaResp queryResultWithColumns;
|
||||
@@ -323,5 +317,9 @@ public class QueryServiceImpl implements QueryService {
|
||||
return queryStructReq;
|
||||
}
|
||||
|
||||
private String getKeyByModelIds(List<Long> modelIds) {
|
||||
return String.join(",", modelIds.stream().map(Object::toString).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.PageDimensionReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.PageMetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
package com.tencent.supersonic.semantic.query.service;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.AT_SYMBOL;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.PageDimensionReq;
|
||||
import com.tencent.supersonic.semantic.api.model.request.PageMetricReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DomainResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.query.request.ItemUseReq;
|
||||
import com.tencent.supersonic.semantic.api.query.response.ItemUseResp;
|
||||
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.DomainService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.AT_SYMBOL;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SchemaServiceImpl implements SchemaService {
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.tencent.supersonic.semantic.query.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.semantic.query.utils.QueryUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -36,8 +37,8 @@ public class SemanticQueryEngineImpl implements SemanticQueryEngine {
|
||||
if (queryExecutor != null) {
|
||||
queryResultWithColumns = queryExecutor.execute(catalog, queryStatement);
|
||||
queryResultWithColumns.setSql(queryStatement.getSql());
|
||||
if (queryStatement.getModelId() > 0) {
|
||||
queryUtils.fillItemNameInfo(queryResultWithColumns, queryStatement.getModelId());
|
||||
if (!CollectionUtils.isEmpty(queryStatement.getModelIds())) {
|
||||
queryUtils.fillItemNameInfo(queryResultWithColumns, queryStatement.getModelIds());
|
||||
}
|
||||
}
|
||||
return queryResultWithColumns;
|
||||
@@ -46,7 +47,7 @@ public class SemanticQueryEngineImpl implements SemanticQueryEngine {
|
||||
public QueryStatement plan(QueryStructReq queryStructCmd) throws Exception {
|
||||
QueryStatement queryStatement = queryParser.logicSql(queryStructCmd);
|
||||
queryUtils.checkSqlParse(queryStatement);
|
||||
queryStatement.setModelId(queryStructCmd.getModelId());
|
||||
queryStatement.setModelIds(queryStructCmd.getModelIds());
|
||||
log.info("queryStatement:{}", queryStatement);
|
||||
return optimize(queryStructCmd, queryStatement);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.tencent.supersonic.semantic.query.parser.calcite.CalciteSqlParser;
|
||||
import com.tencent.supersonic.semantic.query.parser.convert.CalculateAggConverter;
|
||||
import com.tencent.supersonic.semantic.query.parser.convert.DefaultDimValueConverter;
|
||||
import com.tencent.supersonic.semantic.query.parser.convert.MetricCheckConverter;
|
||||
import com.tencent.supersonic.semantic.query.parser.convert.MultiSourceJoin;
|
||||
import com.tencent.supersonic.semantic.query.parser.convert.ParserDefaultConverter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -83,7 +82,6 @@ public class ComponentFactory {
|
||||
semanticConverters.add(getBean("DefaultDimValueConverter", DefaultDimValueConverter.class));
|
||||
semanticConverters.add(getBean("CalculateAggConverter", CalculateAggConverter.class));
|
||||
semanticConverters.add(getBean("ParserDefaultConverter", ParserDefaultConverter.class));
|
||||
semanticConverters.add(getBean("MultiSourceJoin", MultiSourceJoin.class));
|
||||
}
|
||||
|
||||
private static void initQueryExecutors() {
|
||||
|
||||
@@ -1,35 +1,32 @@
|
||||
package com.tencent.supersonic.semantic.query.utils;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.MINUS;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authorization.pojo.AuthRes;
|
||||
import com.tencent.supersonic.auth.api.authorization.pojo.AuthResGrp;
|
||||
import com.tencent.supersonic.auth.api.authorization.pojo.DimensionFilter;
|
||||
import com.tencent.supersonic.auth.api.authorization.request.QueryAuthResReq;
|
||||
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
|
||||
import com.tencent.supersonic.auth.api.authorization.service.AuthService;
|
||||
import com.tencent.supersonic.common.pojo.QueryAuthorization;
|
||||
import com.tencent.supersonic.common.pojo.QueryColumn;
|
||||
import com.tencent.supersonic.common.pojo.enums.AuthType;
|
||||
import com.tencent.supersonic.common.pojo.enums.SensitiveLevelEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import com.tencent.supersonic.common.pojo.Filter;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
|
||||
import com.tencent.supersonic.common.pojo.Constants;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import com.tencent.supersonic.common.pojo.exception.InvalidPermissionException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import com.tencent.supersonic.semantic.query.service.AuthCommonService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -37,40 +34,21 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.MetricService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.assertj.core.util.Sets;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.MINUS;
|
||||
|
||||
@Component
|
||||
@Aspect
|
||||
@Slf4j
|
||||
public class DataPermissionAOP {
|
||||
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper().setDateFormat(
|
||||
new SimpleDateFormat(Constants.DAY_FORMAT));
|
||||
@Autowired
|
||||
private QueryStructUtils queryStructUtils;
|
||||
@Autowired
|
||||
private AuthService authService;
|
||||
@Autowired
|
||||
private DimensionService dimensionService;
|
||||
@Autowired
|
||||
private MetricService metricService;
|
||||
@Autowired
|
||||
private ModelService modelService;
|
||||
@Autowired
|
||||
private AuthCommonService authCommonService;
|
||||
@Value("${permission.data.enable:true}")
|
||||
private Boolean permissionDataEnable;
|
||||
|
||||
@@ -93,27 +71,29 @@ public class DataPermissionAOP {
|
||||
throw new RuntimeException("lease provide user information");
|
||||
}
|
||||
//1. determine whether admin of the model
|
||||
if (doModelAdmin(user, queryStructReq)) {
|
||||
if (authCommonService.doModelAdmin(user, queryStructReq.getModelIds())) {
|
||||
return point.proceed();
|
||||
}
|
||||
|
||||
// 2. determine whether the subject field is visible
|
||||
doModelVisible(user, queryStructReq);
|
||||
authCommonService.doModelVisible(user, queryStructReq.getModelIds());
|
||||
|
||||
// 3. fetch data permission meta information
|
||||
Long modelId = queryStructReq.getModelId();
|
||||
List<Long> modelIds = queryStructReq.getModelIds();
|
||||
Set<String> res4Privilege = queryStructUtils.getResNameEnExceptInternalCol(queryStructReq);
|
||||
log.info("modelId:{}, res4Privilege:{}", modelId, res4Privilege);
|
||||
log.info("modelId:{}, res4Privilege:{}", modelIds, res4Privilege);
|
||||
|
||||
Set<String> sensitiveResByModel = getHighSensitiveColsByModelId(modelId);
|
||||
Set<String> sensitiveResByModel = authCommonService.getHighSensitiveColsByModelId(modelIds);
|
||||
Set<String> sensitiveResReq = res4Privilege.parallelStream()
|
||||
.filter(sensitiveResByModel::contains).collect(Collectors.toSet());
|
||||
log.info("this query domainId:{}, sensitiveResReq:{}", modelId, sensitiveResReq);
|
||||
log.info("this query domainId:{}, sensitiveResReq:{}", modelIds, sensitiveResReq);
|
||||
|
||||
// query user privilege info
|
||||
AuthorizedResourceResp authorizedResource = getAuthorizedResource(user, modelId, sensitiveResReq);
|
||||
AuthorizedResourceResp authorizedResource = authCommonService.getAuthorizedResource(user,
|
||||
modelIds, sensitiveResReq);
|
||||
// get sensitiveRes that user has privilege
|
||||
Set<String> resAuthSet = getAuthResNameSet(authorizedResource, queryStructReq.getModelId());
|
||||
Set<String> resAuthSet = authCommonService.getAuthResNameSet(authorizedResource,
|
||||
queryStructReq.getModelIds());
|
||||
|
||||
// 4.if sensitive fields without permission are involved in filter, thrown an exception
|
||||
doFilterCheckLogic(queryStructReq, resAuthSet, sensitiveResReq);
|
||||
@@ -127,115 +107,20 @@ public class DataPermissionAOP {
|
||||
if (CollectionUtils.isEmpty(sensitiveResReq) || allSensitiveResReqIsOk(sensitiveResReq, resAuthSet)) {
|
||||
// if sensitiveRes is empty
|
||||
log.info("sensitiveResReq is empty");
|
||||
return getQueryResultWithColumns(queryResultWithColumns, modelId, authorizedResource);
|
||||
return authCommonService.getQueryResultWithColumns(queryResultWithColumns, modelIds, authorizedResource);
|
||||
}
|
||||
|
||||
// 6.if the column has no permission, hit *
|
||||
Set<String> need2Apply = sensitiveResReq.stream().filter(req -> !resAuthSet.contains(req))
|
||||
.collect(Collectors.toSet());
|
||||
QueryResultWithSchemaResp queryResultAfterDesensitization = desensitizationData(queryResultWithColumns,
|
||||
need2Apply);
|
||||
addPromptInfoInfo(modelId, queryResultAfterDesensitization, authorizedResource, need2Apply);
|
||||
QueryResultWithSchemaResp queryResultAfterDesensitization =
|
||||
authCommonService.desensitizationData(queryResultWithColumns, need2Apply);
|
||||
authCommonService.addPromptInfoInfo(modelIds, queryResultAfterDesensitization, authorizedResource, need2Apply);
|
||||
|
||||
return queryResultAfterDesensitization;
|
||||
|
||||
}
|
||||
|
||||
private boolean doModelAdmin(User user, QueryStructReq queryStructReq) {
|
||||
Long modelId = queryStructReq.getModelId();
|
||||
List<ModelResp> modelListAdmin = modelService.getModelListWithAuth(user, null, AuthType.ADMIN);
|
||||
if (CollectionUtils.isEmpty(modelListAdmin)) {
|
||||
return false;
|
||||
} else {
|
||||
Map<Long, List<ModelResp>> id2modelResp = modelListAdmin.stream()
|
||||
.collect(Collectors.groupingBy(SchemaItem::getId));
|
||||
return !CollectionUtils.isEmpty(id2modelResp) && id2modelResp.containsKey(modelId);
|
||||
}
|
||||
}
|
||||
|
||||
private void doModelVisible(User user, QueryStructReq queryStructReq) {
|
||||
Boolean visible = true;
|
||||
Long modelId = queryStructReq.getModelId();
|
||||
List<ModelResp> modelListVisible = modelService.getModelListWithAuth(user, null, AuthType.VISIBLE);
|
||||
if (CollectionUtils.isEmpty(modelListVisible)) {
|
||||
visible = false;
|
||||
} else {
|
||||
Map<Long, List<ModelResp>> id2domainDesc = modelListVisible.stream()
|
||||
.collect(Collectors.groupingBy(SchemaItem::getId));
|
||||
if (!CollectionUtils.isEmpty(id2domainDesc) && !id2domainDesc.containsKey(modelId)) {
|
||||
visible = false;
|
||||
}
|
||||
}
|
||||
if (!visible) {
|
||||
ModelResp modelResp = modelService.getModel(modelId);
|
||||
String modelName = modelResp.getName();
|
||||
List<String> admins = modelService.getModelAdmin(modelResp.getId());
|
||||
String message = String.format("您没有主题域[%s]权限,请联系管理员%s开通", modelName, admins);
|
||||
throw new InvalidPermissionException(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private QueryResultWithSchemaResp getQueryResultWithColumns(QueryResultWithSchemaResp resultWithColumns,
|
||||
Long domainId, AuthorizedResourceResp authResource) {
|
||||
addPromptInfoInfo(domainId, resultWithColumns, authResource, Sets.newHashSet());
|
||||
return resultWithColumns;
|
||||
}
|
||||
|
||||
private void addPromptInfoInfo(Long modelId, QueryResultWithSchemaResp queryResultWithColumns,
|
||||
AuthorizedResourceResp authorizedResource, Set<String> need2Apply) {
|
||||
List<DimensionFilter> filters = authorizedResource.getFilters();
|
||||
if (CollectionUtils.isEmpty(need2Apply) && CollectionUtils.isEmpty(filters)) {
|
||||
return;
|
||||
}
|
||||
List<String> admins = modelService.getModelAdmin(modelId);
|
||||
if (!CollectionUtils.isEmpty(need2Apply)) {
|
||||
String promptInfo = String.format("当前结果已经过脱敏处理, 申请权限请联系管理员%s", admins);
|
||||
queryResultWithColumns.setQueryAuthorization(new QueryAuthorization(promptInfo));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(filters)) {
|
||||
log.debug("dimensionFilters:{}", filters);
|
||||
ModelResp modelResp = modelService.getModel(modelId);
|
||||
List<String> exprList = new ArrayList<>();
|
||||
List<String> descList = new ArrayList<>();
|
||||
filters.stream().forEach(filter -> {
|
||||
descList.add(filter.getDescription());
|
||||
exprList.add(filter.getExpressions().toString());
|
||||
});
|
||||
String promptInfo = "当前结果已经过行权限过滤,详细过滤条件如下:%s, 申请权限请联系管理员%s";
|
||||
String message = String.format(promptInfo, CollectionUtils.isEmpty(descList) ? exprList : descList, admins);
|
||||
|
||||
queryResultWithColumns.setQueryAuthorization(
|
||||
new QueryAuthorization(modelResp.getName(), exprList, descList, message));
|
||||
log.info("queryResultWithColumns:{}", queryResultWithColumns);
|
||||
}
|
||||
}
|
||||
|
||||
private QueryResultWithSchemaResp deepCopyResult(QueryResultWithSchemaResp raw) throws Exception {
|
||||
QueryResultWithSchemaResp queryResultWithColumns = new QueryResultWithSchemaResp();
|
||||
BeanUtils.copyProperties(raw, queryResultWithColumns);
|
||||
|
||||
List<QueryColumn> columns = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(raw.getColumns())) {
|
||||
String columnsStr = MAPPER.writeValueAsString(raw.getColumns());
|
||||
columns = MAPPER.readValue(columnsStr, new TypeReference<List<QueryColumn>>() {
|
||||
});
|
||||
queryResultWithColumns.setColumns(columns);
|
||||
}
|
||||
queryResultWithColumns.setColumns(columns);
|
||||
|
||||
List<Map<String, Object>> resultData = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(raw.getResultList())) {
|
||||
for (Map<String, Object> line : raw.getResultList()) {
|
||||
Map<String, Object> newLine = new HashMap<>();
|
||||
newLine.putAll(line);
|
||||
resultData.add(newLine);
|
||||
}
|
||||
}
|
||||
queryResultWithColumns.setResultList(resultData);
|
||||
return queryResultWithColumns;
|
||||
}
|
||||
|
||||
private boolean allSensitiveResReqIsOk(Set<String> sensitiveResReq, Set<String> resAuthSet) {
|
||||
if (resAuthSet.containsAll(sensitiveResReq)) {
|
||||
return true;
|
||||
@@ -244,50 +129,6 @@ public class DataPermissionAOP {
|
||||
return false;
|
||||
}
|
||||
|
||||
private Set<String> getAuthResNameSet(AuthorizedResourceResp authorizedResource, Long modelId) {
|
||||
Set<String> resAuthName = new HashSet<>();
|
||||
List<AuthResGrp> authResGrpList = authorizedResource.getResources();
|
||||
authResGrpList.stream().forEach(authResGrp -> {
|
||||
List<AuthRes> cols = authResGrp.getGroup();
|
||||
if (!CollectionUtils.isEmpty(cols)) {
|
||||
cols.stream().filter(col -> modelId.equals(col.getModelId()))
|
||||
.forEach(col -> resAuthName.add(col.getName()));
|
||||
}
|
||||
|
||||
});
|
||||
log.info("resAuthName:{}", resAuthName);
|
||||
return resAuthName;
|
||||
}
|
||||
|
||||
private AuthorizedResourceResp getAuthorizedResource(User user, Long domainId,
|
||||
Set<String> sensitiveResReq) {
|
||||
List<AuthRes> resourceReqList = new ArrayList<>();
|
||||
sensitiveResReq.forEach(res -> resourceReqList.add(new AuthRes(domainId, res)));
|
||||
QueryAuthResReq queryAuthResReq = new QueryAuthResReq();
|
||||
queryAuthResReq.setResources(resourceReqList);
|
||||
queryAuthResReq.setModelId(domainId);
|
||||
AuthorizedResourceResp authorizedResource = fetchAuthRes(queryAuthResReq, user);
|
||||
log.info("user:{}, domainId:{}, after queryAuthorizedResources:{}", user.getName(), domainId,
|
||||
authorizedResource);
|
||||
return authorizedResource;
|
||||
}
|
||||
|
||||
private Set<String> getHighSensitiveColsByModelId(Long modelId) {
|
||||
Set<String> highSensitiveCols = new HashSet<>();
|
||||
MetaFilter metaFilter = new MetaFilter();
|
||||
metaFilter.setModelIds(Lists.newArrayList(modelId));
|
||||
metaFilter.setSensitiveLevel(SensitiveLevelEnum.HIGH.getCode());
|
||||
List<DimensionResp> highSensitiveDimensions = dimensionService.getDimensions(metaFilter);
|
||||
List<MetricResp> highSensitiveMetrics = metricService.getMetrics(metaFilter);
|
||||
if (!CollectionUtils.isEmpty(highSensitiveDimensions)) {
|
||||
highSensitiveDimensions.stream().forEach(dim -> highSensitiveCols.add(dim.getBizName()));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(highSensitiveMetrics)) {
|
||||
highSensitiveMetrics.stream().forEach(metric -> highSensitiveCols.add(metric.getBizName()));
|
||||
}
|
||||
return highSensitiveCols;
|
||||
}
|
||||
|
||||
private void doRowPermission(QueryStructReq queryStructReq, AuthorizedResourceResp authorizedResource) {
|
||||
log.debug("start doRowPermission logic");
|
||||
StringJoiner joiner = new StringJoiner(" OR ");
|
||||
@@ -320,64 +161,6 @@ public class DataPermissionAOP {
|
||||
|
||||
}
|
||||
|
||||
private QueryResultWithSchemaResp desensitizationData(QueryResultWithSchemaResp raw, Set<String> need2Apply) {
|
||||
log.debug("start desensitizationData logic");
|
||||
if (CollectionUtils.isEmpty(need2Apply)) {
|
||||
log.info("user has all sensitiveRes");
|
||||
return raw;
|
||||
}
|
||||
|
||||
List<QueryColumn> columns = raw.getColumns();
|
||||
|
||||
boolean doDesensitization = false;
|
||||
for (QueryColumn queryColumn : columns) {
|
||||
if (need2Apply.contains(queryColumn.getNameEn())) {
|
||||
doDesensitization = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!doDesensitization) {
|
||||
return raw;
|
||||
}
|
||||
|
||||
QueryResultWithSchemaResp queryResultWithColumns = raw;
|
||||
try {
|
||||
queryResultWithColumns = deepCopyResult(raw);
|
||||
} catch (Exception e) {
|
||||
log.warn("deepCopyResult: ", e);
|
||||
}
|
||||
addAuthorizedSchemaInfo(queryResultWithColumns.getColumns(), need2Apply);
|
||||
desensitizationInternal(queryResultWithColumns.getResultList(), need2Apply);
|
||||
return queryResultWithColumns;
|
||||
}
|
||||
|
||||
private void addAuthorizedSchemaInfo(List<QueryColumn> columns, Set<String> need2Apply) {
|
||||
if (CollectionUtils.isEmpty(need2Apply)) {
|
||||
return;
|
||||
}
|
||||
columns.stream().forEach(col -> {
|
||||
if (need2Apply.contains(col.getNameEn())) {
|
||||
col.setAuthorized(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void desensitizationInternal(List<Map<String, Object>> result, Set<String> need2Apply) {
|
||||
log.info("start desensitizationInternal logic");
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
Map<String, Object> row = result.get(i);
|
||||
Map<String, Object> newRow = new HashMap<>();
|
||||
for (String col : row.keySet()) {
|
||||
if (need2Apply.contains(col)) {
|
||||
newRow.put(col, "****");
|
||||
} else {
|
||||
newRow.put(col, row.get(col));
|
||||
}
|
||||
}
|
||||
result.set(i, newRow);
|
||||
}
|
||||
}
|
||||
|
||||
private void doFilterCheckLogic(QueryStructReq queryStructReq, Set<String> resAuthName,
|
||||
Set<String> sensitiveResReq) {
|
||||
Set<String> resFilterSet = queryStructUtils.getFilterResNameEnExceptInternalCol(queryStructReq);
|
||||
@@ -385,32 +168,18 @@ public class DataPermissionAOP {
|
||||
.filter(res -> !resAuthName.contains(res) && sensitiveResReq.contains(res)).collect(Collectors.toSet());
|
||||
Set<String> nameCnSet = new HashSet<>();
|
||||
|
||||
List<Long> modelIds = new ArrayList<>();
|
||||
modelIds.add(queryStructReq.getModelId());
|
||||
List<ModelResp> modelInfos = modelService.getModelList(modelIds);
|
||||
String modelNameCn = Constants.EMPTY;
|
||||
if (!CollectionUtils.isEmpty(modelInfos)) {
|
||||
modelNameCn = modelInfos.get(0).getName();
|
||||
}
|
||||
|
||||
Map<Long, ModelResp> modelRespMap = modelService.getModelMap();
|
||||
List<Long> modelIds = Lists.newArrayList(queryStructReq.getModelIds());
|
||||
List<DimensionResp> dimensionDescList = dimensionService.getDimensions(new MetaFilter(modelIds));
|
||||
String finalDomainNameCn = modelNameCn;
|
||||
dimensionDescList.stream().filter(dim -> need2Apply.contains(dim.getBizName()))
|
||||
.forEach(dim -> nameCnSet.add(finalDomainNameCn + MINUS + dim.getName()));
|
||||
.forEach(dim -> nameCnSet.add(modelRespMap.get(dim.getModelId()).getName() + MINUS + dim.getName()));
|
||||
|
||||
if (!CollectionUtils.isEmpty(need2Apply)) {
|
||||
ModelResp modelResp = modelInfos.get(0);
|
||||
List<String> admins = modelService.getModelAdmin(modelResp.getId());
|
||||
List<String> admins = modelService.getModelAdmin(modelIds.get(0));
|
||||
log.info("in doFilterLogic, need2Apply:{}", need2Apply);
|
||||
String message = String.format("您没有以下维度%s权限, 请联系管理员%s开通", nameCnSet, admins);
|
||||
throw new InvalidPermissionException(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private AuthorizedResourceResp fetchAuthRes(QueryAuthResReq queryAuthResReq, User user) {
|
||||
log.info("queryAuthResReq:{}", queryAuthResReq);
|
||||
return authService.queryAuthorizedResources(queryAuthResReq, user);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.tencent.supersonic.semantic.query.utils;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.common.pojo.Filter;
|
||||
import com.tencent.supersonic.common.pojo.QueryColumn;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import com.tencent.supersonic.common.util.JsonUtil;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.FieldExpression;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserReplaceHelper;
|
||||
@@ -9,19 +11,9 @@ import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.DimValueMap;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
|
||||
import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum;
|
||||
import com.tencent.supersonic.common.pojo.Filter;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryS2SQLReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -34,6 +26,14 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -56,7 +56,7 @@ public class DimValueAspect {
|
||||
}
|
||||
Object[] args = joinPoint.getArgs();
|
||||
QueryS2SQLReq queryS2SQLReq = (QueryS2SQLReq) args[0];
|
||||
MetaFilter metaFilter = new MetaFilter(Lists.newArrayList(queryS2SQLReq.getModelId()));
|
||||
MetaFilter metaFilter = new MetaFilter(Lists.newArrayList(queryS2SQLReq.getModelIds()));
|
||||
String sql = queryS2SQLReq.getSql();
|
||||
log.info("correctorSql before replacing:{}", sql);
|
||||
// if dimensionvalue is alias,consider the true dimensionvalue.
|
||||
@@ -147,8 +147,7 @@ public class DimValueAspect {
|
||||
|
||||
Object[] args = joinPoint.getArgs();
|
||||
QueryStructReq queryStructReq = (QueryStructReq) args[0];
|
||||
Long modelId = queryStructReq.getModelId();
|
||||
MetaFilter metaFilter = new MetaFilter(Lists.newArrayList(modelId));
|
||||
MetaFilter metaFilter = new MetaFilter(Lists.newArrayList(queryStructReq.getModelIds()));
|
||||
List<DimensionResp> dimensions = dimensionService.getDimensions(metaFilter);
|
||||
Map<String, Map<String, String>> dimAndAliasAndTechNamePair = getAliasAndBizNameToTechName(dimensions);
|
||||
Map<String, Map<String, String>> dimAndTechNameAndBizNamePair = getTechNameToBizName(dimensions);
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
package com.tencent.supersonic.semantic.query.utils;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.DAY;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.DAY_FORMAT;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.MONTH;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.UNDERLINE;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.WEEK;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.Aggregator;
|
||||
import com.tencent.supersonic.common.pojo.DateConf;
|
||||
import com.tencent.supersonic.common.pojo.DateConf.DateMode;
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import com.tencent.supersonic.common.pojo.enums.TypeEnums;
|
||||
import com.tencent.supersonic.common.util.DateModeUtils;
|
||||
import com.tencent.supersonic.common.util.SqlFilterUtils;
|
||||
@@ -23,7 +19,6 @@ import com.tencent.supersonic.semantic.api.model.pojo.SchemaItem;
|
||||
import com.tencent.supersonic.semantic.api.model.request.ModelSchemaFilterReq;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.common.pojo.ItemDateResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.ModelSchemaResp;
|
||||
@@ -33,6 +28,14 @@ import com.tencent.supersonic.semantic.model.domain.Catalog;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.EngineTypeEnum;
|
||||
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
|
||||
import com.tencent.supersonic.semantic.query.service.SchemaService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
@@ -46,14 +49,12 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.DAY;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.DAY_FORMAT;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.MONTH;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.UNDERLINE;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.WEEK;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@@ -95,7 +96,7 @@ public class QueryStructUtils {
|
||||
|
||||
private List<Long> getDimensionIds(QueryStructReq queryStructCmd) {
|
||||
List<Long> dimensionIds = new ArrayList<>();
|
||||
List<DimensionResp> dimensions = catalog.getDimensions(queryStructCmd.getModelId());
|
||||
List<DimensionResp> dimensions = catalog.getDimensions(queryStructCmd.getModelIds());
|
||||
Map<String, List<DimensionResp>> pair = dimensions.stream()
|
||||
.collect(Collectors.groupingBy(DimensionResp::getBizName));
|
||||
for (String group : queryStructCmd.getGroups()) {
|
||||
@@ -116,7 +117,7 @@ public class QueryStructUtils {
|
||||
|
||||
private List<Long> getMetricIds(QueryStructReq queryStructCmd) {
|
||||
List<Long> metricIds = new ArrayList<>();
|
||||
List<MetricResp> metrics = catalog.getMetrics(queryStructCmd.getModelId());
|
||||
List<MetricResp> metrics = catalog.getMetrics(queryStructCmd.getModelIds());
|
||||
Map<String, List<MetricResp>> pair = metrics.stream().collect(Collectors.groupingBy(SchemaItem::getBizName));
|
||||
for (Aggregator agg : queryStructCmd.getAggregators()) {
|
||||
if (pair.containsKey(agg.getColumn())) {
|
||||
@@ -214,7 +215,7 @@ public class QueryStructUtils {
|
||||
Set<String> resNameSet = getResName(queryS2SQLReq);
|
||||
Set<String> resNameEnSet = new HashSet<>();
|
||||
ModelSchemaFilterReq filter = new ModelSchemaFilterReq();
|
||||
List<Long> modelIds = Lists.newArrayList(queryS2SQLReq.getModelId());
|
||||
List<Long> modelIds = Lists.newArrayList(queryS2SQLReq.getModelIds());
|
||||
filter.setModelIds(modelIds);
|
||||
List<ModelSchemaResp> modelSchemaRespList = schemaService.fetchModelSchema(filter, user);
|
||||
if (!CollectionUtils.isEmpty(modelSchemaRespList)) {
|
||||
@@ -256,14 +257,16 @@ public class QueryStructUtils {
|
||||
if (CollectionUtils.isEmpty(groups)) {
|
||||
log.warn("group is empty!");
|
||||
} else {
|
||||
String group = groups.get(0).equalsIgnoreCase("sys_imp_date")
|
||||
? groups.get(1) : groups.get(0);
|
||||
DimensionResp dimension = catalog.getDimension(group, modelId);
|
||||
String datasourceBizName = dimension.getDatasourceBizName();
|
||||
if (Strings.isNotEmpty(datasourceBizName)) {
|
||||
internalMetricNamePrefix = datasourceBizName + UNDERLINE;
|
||||
for (int i = 0; i < groups.size(); i++) {
|
||||
if (groups.get(i).equalsIgnoreCase("sys_imp_date")) {
|
||||
continue;
|
||||
}
|
||||
DimensionResp dimension = catalog.getDimension(groups.get(i), modelId);
|
||||
if (Objects.nonNull(dimension) && Strings.isNotEmpty(dimension.getModelBizName())) {
|
||||
internalMetricNamePrefix = dimension.getModelBizName() + UNDERLINE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
String internalMetricName = internalMetricNamePrefix + internalMetricNameSuffix;
|
||||
return internalMetricName;
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
package com.tencent.supersonic.semantic.query.utils;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.JOIN_UNDERLINE;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.UNIONALL;
|
||||
|
||||
import com.tencent.supersonic.common.pojo.Aggregator;
|
||||
import com.tencent.supersonic.common.pojo.Constants;
|
||||
import com.tencent.supersonic.common.pojo.QueryColumn;
|
||||
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;
|
||||
import com.tencent.supersonic.common.util.cache.CacheUtils;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.SemanticTypeEnum;
|
||||
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.response.DimensionResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.MetricResp;
|
||||
import com.tencent.supersonic.semantic.api.model.response.QueryResultWithSchemaResp;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryMultiStructReq;
|
||||
import com.tencent.supersonic.semantic.model.domain.Catalog;
|
||||
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -26,12 +30,9 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.PostConstruct;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.JOIN_UNDERLINE;
|
||||
import static com.tencent.supersonic.common.pojo.Constants.UNIONALL;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@@ -67,9 +68,9 @@ public class QueryUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public void fillItemNameInfo(QueryResultWithSchemaResp queryResultWithColumns, Long modelId) {
|
||||
List<MetricResp> metricDescList = catalog.getMetrics(modelId);
|
||||
List<DimensionResp> dimensionDescList = catalog.getDimensions(modelId);
|
||||
public void fillItemNameInfo(QueryResultWithSchemaResp queryResultWithColumns, List<Long> modelIds) {
|
||||
List<MetricResp> metricDescList = catalog.getMetrics(modelIds);
|
||||
List<DimensionResp> dimensionDescList = catalog.getDimensions(modelIds);
|
||||
Map<String, MetricResp> metricRespMap =
|
||||
metricDescList.stream().collect(Collectors.toMap(MetricResp::getBizName, a -> a, (k1, k2) -> k1));
|
||||
Map<String, String> namePair = new HashMap<>();
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.tencent.supersonic.semantic.query.utils;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.MINUS;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.auth.api.authorization.response.AuthorizedResourceResp;
|
||||
import com.tencent.supersonic.common.pojo.Constants;
|
||||
@@ -15,14 +14,8 @@ import com.tencent.supersonic.semantic.api.query.request.QueryS2SQLReq;
|
||||
import com.tencent.supersonic.semantic.model.domain.DimensionService;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.MetaFilter;
|
||||
import com.tencent.supersonic.semantic.model.domain.pojo.ModelFilter;
|
||||
import com.tencent.supersonic.semantic.query.service.AuthCommonService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
@@ -38,6 +31,16 @@ import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.tencent.supersonic.common.pojo.Constants.MINUS;
|
||||
|
||||
@Component
|
||||
@Aspect
|
||||
@Order(1)
|
||||
@@ -72,29 +75,29 @@ public class S2SQLDataAspect {
|
||||
if (Objects.isNull(user) || Strings.isNullOrEmpty(user.getName())) {
|
||||
throw new RuntimeException("please provide user information");
|
||||
}
|
||||
Long modelId = queryS2SQLReq.getModelId();
|
||||
List<Long> modelIds = queryS2SQLReq.getModelIds();
|
||||
|
||||
//1. determine whether admin of the model
|
||||
if (authCommonService.doModelAdmin(user, modelId)) {
|
||||
if (authCommonService.doModelAdmin(user, modelIds)) {
|
||||
log.info("determine whether admin of the model!");
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
// 2. determine whether the subject field is visible
|
||||
authCommonService.doModelVisible(user, modelId);
|
||||
authCommonService.doModelVisible(user, modelIds);
|
||||
// 3. fetch data permission meta information
|
||||
Set<String> res4Privilege = queryStructUtils.getResNameEnExceptInternalCol(queryS2SQLReq, user);
|
||||
log.info("modelId:{}, res4Privilege:{}", modelId, res4Privilege);
|
||||
log.info("modelId:{}, res4Privilege:{}", modelIds, res4Privilege);
|
||||
|
||||
Set<String> sensitiveResByModel = authCommonService.getHighSensitiveColsByModelId(modelId);
|
||||
Set<String> sensitiveResByModel = authCommonService.getHighSensitiveColsByModelId(modelIds);
|
||||
Set<String> sensitiveResReq = res4Privilege.parallelStream()
|
||||
.filter(sensitiveResByModel::contains).collect(Collectors.toSet());
|
||||
log.info("this query domainId:{}, sensitiveResReq:{}", modelId, sensitiveResReq);
|
||||
log.info("this query domainId:{}, sensitiveResReq:{}", modelIds, sensitiveResReq);
|
||||
|
||||
// query user privilege info
|
||||
AuthorizedResourceResp authorizedResource = authCommonService
|
||||
.getAuthorizedResource(user, modelId, sensitiveResReq);
|
||||
.getAuthorizedResource(user, modelIds, sensitiveResReq);
|
||||
// get sensitiveRes that user has privilege
|
||||
Set<String> resAuthSet = authCommonService.getAuthResNameSet(authorizedResource, modelId);
|
||||
Set<String> resAuthSet = authCommonService.getAuthResNameSet(authorizedResource, modelIds);
|
||||
|
||||
// 4.if sensitive fields without permission are involved in filter, thrown an exception
|
||||
doFilterCheckLogic(queryS2SQLReq, resAuthSet, sensitiveResReq);
|
||||
@@ -109,7 +112,7 @@ public class S2SQLDataAspect {
|
||||
.allSensitiveResReqIsOk(sensitiveResReq, resAuthSet)) {
|
||||
// if sensitiveRes is empty
|
||||
log.info("sensitiveResReq is empty");
|
||||
return authCommonService.getQueryResultWithColumns(queryResultWithColumns, modelId, authorizedResource);
|
||||
return authCommonService.getQueryResultWithColumns(queryResultWithColumns, modelIds, authorizedResource);
|
||||
}
|
||||
|
||||
// 6.if the column has no permission, hit *
|
||||
@@ -118,7 +121,7 @@ public class S2SQLDataAspect {
|
||||
log.info("need2Apply:{},sensitiveResReq:{},resAuthSet:{}", need2Apply, sensitiveResReq, resAuthSet);
|
||||
QueryResultWithSchemaResp queryResultAfterDesensitization = authCommonService
|
||||
.desensitizationData(queryResultWithColumns, need2Apply);
|
||||
authCommonService.addPromptInfoInfo(modelId, queryResultAfterDesensitization, authorizedResource, need2Apply);
|
||||
authCommonService.addPromptInfoInfo(modelIds, queryResultAfterDesensitization, authorizedResource, need2Apply);
|
||||
|
||||
return queryResultAfterDesensitization;
|
||||
}
|
||||
@@ -163,9 +166,10 @@ public class S2SQLDataAspect {
|
||||
.filter(res -> !resAuthName.contains(res) && sensitiveResReq.contains(res)).collect(Collectors.toSet());
|
||||
Set<String> nameCnSet = new HashSet<>();
|
||||
|
||||
List<Long> modelIds = new ArrayList<>();
|
||||
modelIds.add(queryS2SQLReq.getModelId());
|
||||
List<ModelResp> modelInfos = modelService.getModelList(modelIds);
|
||||
List<Long> modelIds = Lists.newArrayList(queryS2SQLReq.getModelIds());
|
||||
ModelFilter modelFilter = new ModelFilter();
|
||||
modelFilter.setModelIds(modelIds);
|
||||
List<ModelResp> modelInfos = modelService.getModelList(modelFilter);
|
||||
String modelNameCn = Constants.EMPTY;
|
||||
if (!CollectionUtils.isEmpty(modelInfos)) {
|
||||
modelNameCn = modelInfos.get(0).getName();
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.tencent.supersonic.auth.api.authentication.pojo.User;
|
||||
import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum;
|
||||
import com.tencent.supersonic.common.util.SqlFilterUtils;
|
||||
import com.tencent.supersonic.common.util.jsqlparser.SqlParserSelectHelper;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.QueryOptMode;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.QueryTypeBackEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.QueryTypeEnum;
|
||||
import com.tencent.supersonic.semantic.api.model.pojo.QueryStat;
|
||||
@@ -17,23 +18,20 @@ import com.tencent.supersonic.semantic.api.query.request.QueryS2SQLReq;
|
||||
import com.tencent.supersonic.semantic.api.query.request.QueryStructReq;
|
||||
import com.tencent.supersonic.semantic.api.query.response.ItemUseResp;
|
||||
import com.tencent.supersonic.semantic.model.domain.ModelService;
|
||||
import com.tencent.supersonic.semantic.api.model.enums.QueryOptMode;
|
||||
|
||||
import com.tencent.supersonic.semantic.query.persistence.repository.StatRepository;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -91,23 +89,20 @@ public class StatUtils {
|
||||
public void initStatInfo(QueryS2SQLReq queryS2SQLReq, User facadeUser) {
|
||||
QueryStat queryStatInfo = new QueryStat();
|
||||
List<String> allFields = SqlParserSelectHelper.getAllFields(queryS2SQLReq.getSql());
|
||||
queryStatInfo.setModelId(queryS2SQLReq.getModelId());
|
||||
ModelSchemaResp modelSchemaResp = modelService.fetchSingleModelSchema(queryS2SQLReq.getModelId());
|
||||
queryStatInfo.setModelId(queryS2SQLReq.getModelIds().get(0));
|
||||
ModelSchemaResp modelSchemaResp = modelService.fetchSingleModelSchema(queryS2SQLReq.getModelIds().get(0));
|
||||
|
||||
List<String> dimensions = new ArrayList<>();
|
||||
if (Objects.nonNull(modelSchemaResp)) {
|
||||
dimensions = getFieldNames(allFields, modelSchemaResp.getDimensions());
|
||||
}
|
||||
|
||||
List<String> metrics = new ArrayList<>();
|
||||
if (Objects.nonNull(modelSchemaResp)) {
|
||||
dimensions = getFieldNames(allFields, modelSchemaResp.getDimensions());
|
||||
metrics = getFieldNames(allFields, modelSchemaResp.getMetrics());
|
||||
}
|
||||
|
||||
String userName = getUserName(facadeUser);
|
||||
try {
|
||||
queryStatInfo.setTraceId("")
|
||||
.setModelId(queryS2SQLReq.getModelId())
|
||||
.setModelId(queryS2SQLReq.getModelIds().get(0))
|
||||
.setUser(userName)
|
||||
.setQueryType(QueryTypeEnum.SQL.getValue())
|
||||
.setQueryTypeBack(QueryTypeBackEnum.NORMAL.getState())
|
||||
@@ -137,7 +132,7 @@ public class StatUtils {
|
||||
|
||||
try {
|
||||
queryStatInfo.setTraceId(traceId)
|
||||
.setModelId(queryStructCmd.getModelId())
|
||||
.setModelId(1L)
|
||||
.setUser(user)
|
||||
.setQueryType(QueryTypeEnum.STRUCT.getValue())
|
||||
.setQueryTypeBack(QueryTypeBackEnum.NORMAL.getState())
|
||||
|
||||
@@ -10,9 +10,10 @@ import com.tencent.supersonic.semantic.query.parser.QueryParser;
|
||||
import com.tencent.supersonic.semantic.query.persistence.pojo.QueryStatement;
|
||||
import com.tencent.supersonic.semantic.query.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.semantic.query.utils.QueryUtils;
|
||||
import java.util.Arrays;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Slf4j
|
||||
public class MaterializationQueryTest {
|
||||
|
||||
@@ -43,7 +44,7 @@ public class MaterializationQueryTest {
|
||||
try {
|
||||
QueryStatement queryStatement = queryParser.logicSql(queryStructReq);
|
||||
queryUtils.checkSqlParse(queryStatement);
|
||||
queryStatement.setModelId(queryStructReq.getModelId());
|
||||
queryStatement.setModelIds(queryStructReq.getModelIds());
|
||||
log.info("queryStatement:{}", queryStatement);
|
||||
for (QueryOptimizer queryOptimizer : ComponentFactory.getQueryOptimizers()) {
|
||||
queryOptimizer.rewrite(queryStructReq, queryStatement);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user