Browse Source

init

augit-log
Draven 4 months ago
parent
commit
771e9342c0
  1. 60
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/AuditMessage.java
  2. 92
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/AuditPublishService.java
  3. 28
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/AuditSubscriber.java
  4. 42
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/AuditSubscriberImpl.java
  5. 21
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/OperatorLog.java
  6. 108
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/OperatorLogAspect.java
  7. 8
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AuditLogController.java
  8. 4
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java
  9. 10
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java
  10. 20
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AuditService.java
  11. 38
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/AuditServiceImpl.java
  12. 80
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/utils/AuditLogUtils.java
  13. 23
      dolphinscheduler-api/src/main/resources/application.yaml
  14. 7
      dolphinscheduler-api/src/main/resources/logback-spring.xml
  15. 9
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/audit/AuditSubscriberTest.java
  16. 4
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/AuditServiceTest.java
  17. 1
      dolphinscheduler-bom/pom.xml
  18. 102
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/Audit/AuditObjectType.java
  19. 34
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/Audit/AuditOperationType.java
  20. 61
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/AuditResourceType.java
  21. 62
      dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/AuditLog.java
  22. 6
      dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/AuditLogMapper.java
  23. 22
      dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/AuditLogMapper.xml
  24. 1
      dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/AuditLogMapperTest.java
  25. 1
      dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessServiceImpl.java

60
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/AuditMessage.java

@ -17,70 +17,32 @@
package org.apache.dolphinscheduler.api.audit;
import org.apache.dolphinscheduler.common.enums.AuditOperationType;
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
import lombok.Data;
import org.apache.dolphinscheduler.common.enums.Audit.AuditObjectType;
import org.apache.dolphinscheduler.common.enums.Audit.AuditOperationType;
import org.apache.dolphinscheduler.dao.entity.User;
import java.util.Date;
@Data
public class AuditMessage {
private User user;
private Date auditDate;
private AuditResourceType resourceType;
private AuditObjectType objectType;
private AuditOperationType operation;
private AuditOperationType operationType;
private Integer resourceId;
public AuditMessage(User user, Date auditDate, AuditResourceType resourceType, AuditOperationType operation,
public AuditMessage(User user, Date auditDate, AuditObjectType objectType, AuditOperationType operationType,
Integer resourceId) {
this.user = user;
this.auditDate = auditDate;
this.resourceType = resourceType;
this.operation = operation;
this.resourceId = resourceId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Date getAuditDate() {
return auditDate;
}
public void setAuditDate(Date auditDate) {
this.auditDate = auditDate;
}
public AuditResourceType getResourceType() {
return resourceType;
}
public void setResourceType(AuditResourceType resourceType) {
this.resourceType = resourceType;
}
public AuditOperationType getOperation() {
return operation;
}
public void setOperation(AuditOperationType operation) {
this.operation = operation;
}
public Integer getResourceId() {
return resourceId;
}
public void setResourceId(Integer resourceId) {
this.objectType = objectType;
this.operationType = operationType;
this.resourceId = resourceId;
}
@ -89,8 +51,8 @@ public class AuditMessage {
return "AuditMessage{"
+ "user=" + user
+ ", Date=" + auditDate
+ ", resourceType" + resourceType
+ ", operation=" + operation
+ ", objectType" + objectType
+ ", operationType=" + operationType
+ ", resourceId='" + resourceId + '\'';
}
}

92
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/AuditPublishService.java

@ -1,92 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.api.audit;
import org.apache.dolphinscheduler.api.configuration.ApiConfig;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import javax.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class AuditPublishService {
private final BlockingQueue<AuditMessage> auditMessageQueue = new LinkedBlockingQueue<>();
@Autowired
private List<AuditSubscriber> subscribers;
@Autowired
private ApiConfig apiConfig;
/**
* create a daemon thread to process the message queue
*/
@PostConstruct
private void init() {
if (apiConfig.isAuditEnable()) {
Thread thread = new Thread(this::doPublish);
thread.setDaemon(true);
thread.setName("Audit-Log-Consume-Thread");
thread.start();
}
}
/**
* publish a new audit message
*
* @param message audit message
*/
public void publish(AuditMessage message) {
if (apiConfig.isAuditEnable() && !auditMessageQueue.offer(message)) {
log.error("Publish audit message failed, message:{}", message);
}
}
/**
* subscribers execute the message processor method
*/
private void doPublish() {
AuditMessage message = null;
while (true) {
try {
message = auditMessageQueue.take();
for (AuditSubscriber subscriber : subscribers) {
try {
subscriber.execute(message);
} catch (Exception e) {
log.error("Consume audit message failed, message:{}", message, e);
}
}
} catch (InterruptedException e) {
log.error("Consume audit message failed, message:{}", message, e);
Thread.currentThread().interrupt();
break;
}
}
}
}

28
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/AuditSubscriber.java

@ -1,28 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.api.audit;
public interface AuditSubscriber {
/**
* process the audit message
*
* @param message
*/
void execute(AuditMessage message);
}

42
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/AuditSubscriberImpl.java

@ -1,42 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.api.audit;
import org.apache.dolphinscheduler.dao.entity.AuditLog;
import org.apache.dolphinscheduler.dao.mapper.AuditLogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class AuditSubscriberImpl implements AuditSubscriber {
@Autowired
private AuditLogMapper logMapper;
@Override
public void execute(AuditMessage message) {
AuditLog auditLog = new AuditLog();
auditLog.setUserId(message.getUser().getId());
auditLog.setResourceType(message.getResourceType().getCode());
auditLog.setOperation(message.getOperation().getCode());
auditLog.setTime(message.getAuditDate());
auditLog.setResourceId(message.getResourceId());
logMapper.insert(auditLog);
}
}

21
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/OperatorLog.java

@ -0,0 +1,21 @@
package org.apache.dolphinscheduler.api.audit;
import org.apache.dolphinscheduler.common.enums.Audit.AuditObjectType;
import org.apache.dolphinscheduler.common.enums.Audit.AuditOperationType;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperatorLog {
String describe() default "";
AuditObjectType objectType() default AuditObjectType.PROJECT;
AuditOperationType operationType() default AuditOperationType.CREATE;
}

108
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/OperatorLogAspect.java

@ -0,0 +1,108 @@
package org.apache.dolphinscheduler.api.audit;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import org.apache.dolphinscheduler.api.service.AuditService;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.Audit.AuditOperationType;
import org.apache.dolphinscheduler.dao.entity.AuditLog;
import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class OperatorLogAspect {
@Autowired
private AuditService auditService;
@Autowired
private ProjectMapper projectMapper;
@Pointcut("@annotation(OperatorLog)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
OperatorLog sysLog = method.getAnnotation(OperatorLog.class);
if (sysLog == null) {
return null;
}
Object[] args = point.getArgs();
String[] strings = signature.getParameterNames();
User user = null;
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < strings.length; i++) {
map.put(strings[i], args[i]);
if (args[i] instanceof User) {
user = (User)args[i];
}
}
AuditLog auditLog = new AuditLog();
auditLog.setUserId(user.getId());
auditLog.setObjectType(sysLog.objectType().getCode());
auditLog.setOperationType(sysLog.operationType().getCode());
auditLog.setTime(new Date());
if(sysLog.operationType().equals(AuditOperationType.DELETE)){
// need to get the name before real deleted
switch (sysLog.objectType()){
case PROJECT:
Project project = projectMapper.queryByCode((long)map.get("code"));
auditLog.setDetail(project.getName());
auditLog.setObjectId(project.getId());
default:
break;
}
}
long beginTime = System.currentTimeMillis();
Object result = point.proceed();
long time = System.currentTimeMillis() - beginTime;
saveLog(result, sysLog, auditLog);
return result;
}
private void saveLog(Object object, OperatorLog sysLog, AuditLog auditLog) {
Result result = (Result)object;
if(result.isFailed()) {
return;
}
auditService.addAudit(auditLog);
}
public static int getId(Object obj) {
try {
Field idField = obj.getClass().getDeclaredField("id");
idField.setAccessible(true);
return (int) idField.get(obj);
} catch (NoSuchFieldException | IllegalAccessException | ClassCastException e) {
e.printStackTrace();
}
return -1;
}
}

8
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AuditLogController.java

@ -25,8 +25,8 @@ import org.apache.dolphinscheduler.api.service.AuditService;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.constants.Constants;
import org.apache.dolphinscheduler.common.enums.AuditOperationType;
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
import org.apache.dolphinscheduler.common.enums.Audit.AuditObjectType;
import org.apache.dolphinscheduler.common.enums.Audit.AuditOperationType;
import org.apache.dolphinscheduler.dao.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
@ -69,7 +69,7 @@ public class AuditLogController extends BaseController {
@Parameters({
@Parameter(name = "startDate", description = "START_DATE", schema = @Schema(implementation = String.class)),
@Parameter(name = "endDate", description = "END_DATE", schema = @Schema(implementation = String.class)),
@Parameter(name = "resourceType", description = "RESOURCE_TYPE", schema = @Schema(implementation = AuditResourceType.class)),
@Parameter(name = "resourceType", description = "RESOURCE_TYPE", schema = @Schema(implementation = AuditObjectType.class)),
@Parameter(name = "operationType", description = "OPERATION_TYPE", schema = @Schema(implementation = AuditOperationType.class)),
@Parameter(name = "userName", description = "USER_NAME", schema = @Schema(implementation = String.class)),
@Parameter(name = "pageNo", description = "PAGE_NO", required = true, schema = @Schema(implementation = int.class, example = "1")),
@ -81,7 +81,7 @@ public class AuditLogController extends BaseController {
public Result<PageInfo<AuditDto>> queryAuditLogListPaging(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam("pageNo") Integer pageNo,
@RequestParam("pageSize") Integer pageSize,
@RequestParam(value = "resourceType", required = false) AuditResourceType resourceType,
@RequestParam(value = "resourceType", required = false) AuditObjectType resourceType,
@RequestParam(value = "operationType", required = false) AuditOperationType operationType,
@RequestParam(value = "startDate", required = false) String startDate,
@RequestParam(value = "endDate", required = false) String endDate,

4
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java

@ -36,12 +36,15 @@ import static org.apache.dolphinscheduler.api.enums.Status.SWITCH_PROCESS_DEFINI
import static org.apache.dolphinscheduler.api.enums.Status.UPDATE_PROCESS_DEFINITION_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.VERIFY_PROCESS_DEFINITION_NAME_UNIQUE_ERROR;
import org.apache.dolphinscheduler.api.audit.OperatorLog;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.exceptions.ApiException;
import org.apache.dolphinscheduler.api.service.ProcessDefinitionService;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.constants.Constants;
import org.apache.dolphinscheduler.common.enums.Audit.AuditObjectType;
import org.apache.dolphinscheduler.common.enums.Audit.AuditOperationType;
import org.apache.dolphinscheduler.common.enums.ProcessExecutionTypeEnum;
import org.apache.dolphinscheduler.common.enums.ReleaseState;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
@ -112,6 +115,7 @@ public class ProcessDefinitionController extends BaseController {
@PostMapping()
@ResponseStatus(HttpStatus.CREATED)
@ApiException(CREATE_PROCESS_DEFINITION_ERROR)
@OperatorLog(describe = "createWorkFlow", objectType = AuditObjectType.WORKFLOW, operationType = AuditOperationType.CREATE)
public Result createProcessDefinition(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode,
@RequestParam(value = "name", required = true) String name,

10
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java

@ -27,10 +27,14 @@ import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROJECT_DETAILS
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_UNAUTHORIZED_PROJECT_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.UPDATE_PROJECT_ERROR;
import org.apache.dolphinscheduler.api.audit.OperatorLog;
import org.apache.dolphinscheduler.api.exceptions.ApiException;
import org.apache.dolphinscheduler.api.service.AuditService;
import org.apache.dolphinscheduler.api.service.ProjectService;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.constants.Constants;
import org.apache.dolphinscheduler.common.enums.Audit.AuditObjectType;
import org.apache.dolphinscheduler.common.enums.Audit.AuditOperationType;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils;
@ -67,6 +71,9 @@ public class ProjectController extends BaseController {
@Autowired
private ProjectService projectService;
@Autowired
private AuditService auditService;
/**
* create project
*
@ -83,6 +90,7 @@ public class ProjectController extends BaseController {
@PostMapping()
@ResponseStatus(HttpStatus.CREATED)
@ApiException(CREATE_PROJECT_ERROR)
@OperatorLog(describe = "createProject", objectType = AuditObjectType.PROJECT, operationType = AuditOperationType.CREATE)
public Result createProject(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam("projectName") String projectName,
@RequestParam(value = "description", required = false) String description) {
@ -107,6 +115,7 @@ public class ProjectController extends BaseController {
@PutMapping(value = "/{code}")
@ResponseStatus(HttpStatus.OK)
@ApiException(UPDATE_PROJECT_ERROR)
@OperatorLog(describe = "updateProject", objectType = AuditObjectType.PROJECT, operationType = AuditOperationType.UPDATE)
public Result updateProject(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@PathVariable("code") Long code,
@RequestParam("projectName") String projectName,
@ -207,6 +216,7 @@ public class ProjectController extends BaseController {
@DeleteMapping(value = "/{code}")
@ResponseStatus(HttpStatus.OK)
@ApiException(DELETE_PROJECT_ERROR)
@OperatorLog(describe = "deleteProject", objectType = AuditObjectType.PROJECT, operationType = AuditOperationType.DELETE)
public Result deleteProject(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@PathVariable("code") Long code) {
return projectService.deleteProject(loginUser, code);

20
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AuditService.java

@ -19,8 +19,9 @@ package org.apache.dolphinscheduler.api.service;
import org.apache.dolphinscheduler.api.dto.AuditDto;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.common.enums.AuditOperationType;
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
import org.apache.dolphinscheduler.common.enums.Audit.AuditObjectType;
import org.apache.dolphinscheduler.common.enums.Audit.AuditOperationType;
import org.apache.dolphinscheduler.dao.entity.AuditLog;
import org.apache.dolphinscheduler.dao.entity.User;
/**
@ -28,15 +29,10 @@ import org.apache.dolphinscheduler.dao.entity.User;
*/
public interface AuditService {
/**
* add new audit record
*
* @param user login user
* @param resourceType resource type
* @param resourceId resource id
* @param operation operation type
*/
void addAudit(User user, AuditResourceType resourceType, Integer resourceId, AuditOperationType operation);
void addAudit(AuditLog auditLog);
void addQuartzLog(int processId);
/**
* query audit log list
@ -51,7 +47,7 @@ public interface AuditService {
* @param pageSize page size
* @return audit log string
*/
PageInfo<AuditDto> queryLogListPaging(User loginUser, AuditResourceType resourceType,
PageInfo<AuditDto> queryLogListPaging(User loginUser, AuditObjectType resourceType,
AuditOperationType operationType, String startTime,
String endTime, String userName,
Integer pageNo, Integer pageSize);

38
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/AuditServiceImpl.java

@ -17,13 +17,11 @@
package org.apache.dolphinscheduler.api.service.impl;
import org.apache.dolphinscheduler.api.audit.AuditMessage;
import org.apache.dolphinscheduler.api.audit.AuditPublishService;
import org.apache.dolphinscheduler.api.dto.AuditDto;
import org.apache.dolphinscheduler.api.service.AuditService;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.common.enums.AuditOperationType;
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
import org.apache.dolphinscheduler.common.enums.Audit.AuditObjectType;
import org.apache.dolphinscheduler.common.enums.Audit.AuditOperationType;
import org.apache.dolphinscheduler.dao.entity.AuditLog;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.AuditLogMapper;
@ -44,20 +42,20 @@ public class AuditServiceImpl extends BaseServiceImpl implements AuditService {
@Autowired
private AuditLogMapper auditLogMapper;
@Autowired
private AuditPublishService publishService;
@Override
public void addAudit(AuditLog auditLog) {
auditLogMapper.insert(auditLog);
}
/**
* add new audit log
*
* @param user login user
* @param resourceType resource type
* @param resourceId resource id
* @param operation operation type
*/
@Override
public void addAudit(User user, AuditResourceType resourceType, Integer resourceId, AuditOperationType operation) {
publishService.publish(new AuditMessage(user, new Date(), resourceType, operation, resourceId));
public void addQuartzLog(int processId) {
AuditLog auditLog = new AuditLog();
auditLog.setObjectId(processId);
auditLog.setObjectType(AuditObjectType.WORKFLOW.getCode());
auditLog.setOperationType(AuditOperationType.SCHEDULE_RUN.getCode());
auditLog.setTime(new Date());
auditLog.setUserId(-1);
auditLogMapper.insert(auditLog);
}
/**
@ -75,7 +73,7 @@ public class AuditServiceImpl extends BaseServiceImpl implements AuditService {
*/
@Override
public PageInfo<AuditDto> queryLogListPaging(User loginUser,
AuditResourceType resourceType,
AuditObjectType resourceType,
AuditOperationType operationType,
String startDate,
String endDate,
@ -115,11 +113,11 @@ public class AuditServiceImpl extends BaseServiceImpl implements AuditService {
*/
private AuditDto transformAuditLog(AuditLog auditLog) {
AuditDto auditDto = new AuditDto();
String resourceType = AuditResourceType.of(auditLog.getResourceType()).getMsg();
String resourceType = AuditObjectType.of(auditLog.getObjectType()).getName();
auditDto.setResource(resourceType);
auditDto.setOperation(AuditOperationType.of(auditLog.getOperation()).getMsg());
auditDto.setOperation(AuditOperationType.of(auditLog.getOperationType()).getName());
auditDto.setUserName(auditLog.getUserName());
auditDto.setResourceName(auditLogMapper.queryResourceNameByType(resourceType, auditLog.getResourceId()));
auditDto.setResourceName(auditLogMapper.queryResourceNameByType(resourceType, auditLog.getObjectId()));
auditDto.setTime(auditLog.getTime());
return auditDto;
}

80
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/utils/AuditLogUtils.java

@ -0,0 +1,80 @@
package org.apache.dolphinscheduler.api.utils;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.User;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class AuditLogUtils {
public static void main(String[] args) {
User user1 = new User();
user1.setId(1);
user1.setUserType(UserType.ADMIN_USER);
user1.setEmail("ddd");
User user2 = new User();
user2.setId(3);
user2.setUserType(UserType.ADMIN_USER);
user2.setPhone("1234");
AuditLogUtils.getDiff(user1, user2);
}
public static String getDiff(Object pre, Object now) {
Map<String, Object> map1 = getAllFieldValues(pre);
Map<String, Object> map2 = getAllFieldValues(now);
for (String key1 : map1.keySet()) {
Object valueOld = map1.get(key1);
if(map2.containsKey(key1)) {
Object valueNew = map2.get(key1);
if (!valueOld.equals(valueNew)) {
System.out.println(key1 + " from " + valueOld + " to " + valueNew);
}
} else {
System.out.println(key1 + " value " + valueOld + " deleted");
}
}
for (String key2 : map2.keySet()) {
if(!map1.containsKey(key2)) {
Object valueNew = map2.get(key2);
System.out.println(key2 + " value " + valueNew + " added");
}
}
return "!";
}
public static Map<String, Object> getAllFieldValues(Object obj) {
Class<?> clazz = obj.getClass();
Map<String, Object> map = new HashMap<>();
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
try {
Object value = field.get(obj);
if(!Objects.isNull(value)) {
map.put(field.getName(), value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取父类,直到父类为null
clazz = clazz.getSuperclass();
}
return map;
}
}

23
dolphinscheduler-api/src/main/resources/application.yaml

@ -32,7 +32,7 @@ server:
spring:
profiles:
active: postgresql
active: mysql
banner:
charset: UTF-8
jackson:
@ -121,21 +121,10 @@ management:
application: ${spring.application.name}
registry:
type: zookeeper
zookeeper:
namespace: dolphinscheduler
connect-string: localhost:2181
retry-policy:
base-sleep-time: 60ms
max-sleep: 300ms
max-retries: 5
session-timeout: 60s
connection-timeout: 15s
block-until-connected: 15s
digest: ~
type: jdbc
api:
audit-enable: false
audit-enable: true
# Traffic control, if you turn on this config, the maximum number of request/s will be limited.
# global max request number per second
# default tenant-level max request number
@ -247,9 +236,9 @@ spring:
on-profile: mysql
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/dolphinscheduler
username: root
password: root
url: jdbc:mysql://tidb.intm.aiadgen-int-1.int.infra.webex.com:4000/ds3?useUnicode=true&characterEncoding=UTF-8&enabledTLSProtocols=TLSv1.2
username: udp
password: K$6Uu8U$JlcJWXeT
quartz:
properties:
org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate

7
dolphinscheduler-api/src/main/resources/logback-spring.xml

@ -51,11 +51,6 @@
<logger name="org.apache.hadoop" level="WARN"/>
<root level="INFO">
<if condition="${DOCKER:-false}">
<then>
<appender-ref ref="STDOUT"/>
</then>
</if>
<appender-ref ref="APILOGFILE"/>
<appender-ref ref="STDOUT"/>
</root>
</configuration>

9
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/audit/AuditSubscriberTest.java

@ -17,14 +17,9 @@
package org.apache.dolphinscheduler.api.audit;
import org.apache.dolphinscheduler.common.enums.AuditOperationType;
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
import org.apache.dolphinscheduler.dao.entity.AuditLog;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.AuditLogMapper;
import java.util.Date;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
@ -44,7 +39,7 @@ public class AuditSubscriberTest {
@Test
public void testExecute() {
Mockito.when(logMapper.insert(Mockito.any(AuditLog.class))).thenReturn(1);
auditSubscriber.execute(
new AuditMessage(new User(), new Date(), AuditResourceType.USER_MODULE, AuditOperationType.CREATE, 1));
// auditSubscriber.execute(
// new AuditMessage(new User(), new Date(), AuditResourceType.USER_MODULE, AuditOperationType.CREATE, 1));
}
}

4
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/AuditServiceTest.java

@ -89,8 +89,8 @@ public class AuditServiceTest {
private AuditLog getAuditLog() {
AuditLog auditLog = new AuditLog();
auditLog.setUserName("testName");
auditLog.setOperation(0);
auditLog.setResourceType(0);
auditLog.setOperationType(0);
auditLog.setObjectType(0);
return auditLog;
}
}

1
dolphinscheduler-bom/pom.xml

@ -393,7 +393,6 @@
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector.version}</version>
<scope>test</scope>
</dependency>
<dependency>

102
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/Audit/AuditObjectType.java

@ -0,0 +1,102 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.common.enums.Audit;
import lombok.Getter;
import java.util.*;
/**
* Audit Operation type
*/
public enum AuditObjectType {
PROJECT(0, -1, "Project", true),
RESOURCE(1,-1, "Resource", false),
DATASOURCE(2,-1, "Datasource", true),
SECURITY(3,-1, "Security", false),
WORKFLOW(4,0, "Workflow", true),
WORKFLOW_INSTANCE(5,4, "Workflow instance", true),
TASK(6,5, "Workflow instance", true),
FLINK(7,0, "Flink", true),
ETL(8,0, "Etl", true);
@Getter
private final int code;
@Getter
private final int parentCode;
@Getter
private final String name;
@Getter
private final boolean hasLogs;
@Getter
private int level;
private static final Map<Integer, List<AuditObjectType>> AUDIT_OBJECT_LEVEL_MAP = new HashMap<>();
private static HashMap<Integer, AuditObjectType> AUDIT_OBJECT_MAP = new HashMap<>();
static {
for (AuditObjectType auditObjectType : values()) {
int level = calculateLevel(auditObjectType);
AUDIT_OBJECT_LEVEL_MAP.computeIfAbsent(level, k -> new ArrayList<>()).add(auditObjectType);
auditObjectType.level = level;
AUDIT_OBJECT_MAP.put(auditObjectType.code, auditObjectType);
}
}
public static AuditObjectType of(int status) {
if (AUDIT_OBJECT_MAP.containsKey(status)) {
return AUDIT_OBJECT_MAP.get(status);
}
throw new IllegalArgumentException("invalid audit operation type code " + status);
}
AuditObjectType(int code, int parentCode, String name, boolean hasLogs) {
this.code = code;
this.parentCode = parentCode;
this.name = name;
this.hasLogs = hasLogs;
}
private static int calculateLevel(AuditObjectType auditObjectType) {
int level = 0;
int parentCode = auditObjectType.parentCode;
while (parentCode != -1) {
level++;
parentCode = getParentCode(parentCode);
}
return level;
}
private static int getParentCode(int code) {
for (AuditObjectType objectType : values()) {
if (objectType.code == code) {
return objectType.parentCode;
}
}
return -1;
}
public static void main(String[] args) {
System.out.println(1);
}
}

34
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/AuditOperationType.java → dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/Audit/AuditOperationType.java

@ -15,22 +15,37 @@
* limitations under the License.
*/
package org.apache.dolphinscheduler.common.enums;
package org.apache.dolphinscheduler.common.enums.Audit;
import lombok.Getter;
import java.util.HashMap;
/**
* Audit Operation type
*/
public enum AuditOperationType {
CREATE(0, "CREATE"),
READ(1, "READ"),
UPDATE(2, "UPDATE"),
DELETE(3, "DELETE");
ONLINE(3, "ONLINE"),
START(4, "ONLINE"),
SCHEDULE_RUN(6, "SCHEDULE_RUN"),
RUN(6, "RUN"),
STOP(7, "STOP"),
DELETE(8, "DELETE");
@Getter
private final int code;
private final String enMsg;
@Getter
private final String name;
AuditOperationType(int code, String name) {
this.code = code;
this.name = name;
}
private static HashMap<Integer, AuditOperationType> AUDIT_OPERATION_MAP = new HashMap<>();
@ -40,23 +55,10 @@ public enum AuditOperationType {
}
}
AuditOperationType(int code, String enMsg) {
this.code = code;
this.enMsg = enMsg;
}
public static AuditOperationType of(int status) {
if (AUDIT_OPERATION_MAP.containsKey(status)) {
return AUDIT_OPERATION_MAP.get(status);
}
throw new IllegalArgumentException("invalid audit operation type code " + status);
}
public int getCode() {
return code;
}
public String getMsg() {
return enMsg;
}
}

61
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/AuditResourceType.java

@ -1,61 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dolphinscheduler.common.enums;
import java.util.HashMap;
/**
* Audit Module type
*/
public enum AuditResourceType {
// TODO: add other audit resource enums
USER_MODULE(0, "USER"),
PROJECT_MODULE(1, "PROJECT");
private final int code;
private final String enMsg;
private static HashMap<Integer, AuditResourceType> AUDIT_RESOURCE_MAP = new HashMap<>();
static {
for (AuditResourceType auditResourceType : AuditResourceType.values()) {
AUDIT_RESOURCE_MAP.put(auditResourceType.code, auditResourceType);
}
}
AuditResourceType(int code, String enMsg) {
this.code = code;
this.enMsg = enMsg;
}
public int getCode() {
return this.code;
}
public String getMsg() {
return this.enMsg;
}
public static AuditResourceType of(int status) {
if (AUDIT_RESOURCE_MAP.containsKey(status)) {
return AUDIT_RESOURCE_MAP.get(status);
}
throw new IllegalArgumentException("invalid audit resource type code " + status);
}
}

62
dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/AuditLog.java

@ -23,8 +23,10 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@TableName("t_ds_audit_log")
@Data
@TableName("t_ds_audit_log_1")
public class AuditLog {
/**
@ -39,19 +41,19 @@ public class AuditLog {
private Integer userId;
/**
* resource type
* object type
*/
private Integer resourceType;
private Integer objectType;
/**
* operation type
*/
private Integer operation;
private Integer operationType;
/**
* resource id
* object id
*/
private Integer resourceId;
private Integer objectId;
/**
* user name
@ -64,51 +66,5 @@ public class AuditLog {
*/
private Date time;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public Integer getResourceType() {
return resourceType;
}
public void setResourceType(Integer resourceType) {
this.resourceType = resourceType;
}
public Integer getOperation() {
return operation;
}
public void setOperation(Integer operation) {
this.operation = operation;
}
public Integer getResourceId() {
return resourceId;
}
public void setResourceId(Integer resourceId) {
this.resourceId = resourceId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
private String detail;
}

6
dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/AuditLogMapper.java

@ -32,12 +32,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
public interface AuditLogMapper extends BaseMapper<AuditLog> {
IPage<AuditLog> queryAuditLog(IPage<AuditLog> page,
@Param("resourceType") int[] resourceArray,
@Param("objectType") int[] objectType,
@Param("operationType") int[] operationType,
@Param("userName") String userName,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate);
String queryResourceNameByType(@Param("resourceType") String resourceType,
@Param("resourceId") Integer resourceId);
String queryResourceNameByType(@Param("objectType") String objectType,
@Param("objectId") Integer objectId);
}

22
dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/AuditLogMapper.xml

@ -19,10 +19,10 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="org.apache.dolphinscheduler.dao.mapper.AuditLogMapper">
<sql id="baseSql">
id, user_id, resource_type, operation, resource_id, time
id, user_id, object_type, operation_type, object_id, time, detail
</sql>
<sql id="baseSqlV2">
${alias}.id, ${alias}.user_id, ${alias}.resource_type, ${alias}.operation, ${alias}.resource_id, ${alias}.time
${alias}.id, ${alias}.user_id, ${alias}.object_type, ${alias}.operation_type, ${alias}.object_id, ${alias}.time, ${alias}.detail
</sql>
<select id="queryAuditLog" resultType="org.apache.dolphinscheduler.dao.entity.AuditLog">
@ -32,20 +32,20 @@
</include>
,
u.user_name as user_name
from t_ds_audit_log log
from t_ds_audit_log_1 log
join t_ds_user u on log.user_id = u.id
where 1 = 1
<if test="startDate != null">
and log.time > #{startDate} and log.time <![CDATA[ <=]]> #{endDate}
</if>
<if test="resourceType != null and resourceType.length > 0">
and log.resource_type in
<foreach collection="resourceType" index="index" item="i" open="(" separator="," close=")">
<if test="objectType != null and objectType.length > 0">
and log.object_type in
<foreach collection="objectType" index="index" item="i" open="(" separator="," close=")">
#{i}
</foreach>
</if>
<if test="operationType != null and operationType.length > 0">
and log.operation in
and log.operation_type in
<foreach collection="operationType" index="index" item="j" open="(" separator="," close=")">
#{j}
</foreach>
@ -57,11 +57,11 @@
</select>
<select id="queryResourceNameByType" resultType="String">
<if test="resourceType != null and resourceType == 'USER'">
select user_name from t_ds_user where id = #{resourceId}
<if test="objectType != null and objectType == 'USER'">
select user_name from t_ds_user where id = #{objectId}
</if>
<if test="resourceType != null and resourceType == 'PROJECT'">
select name from t_ds_project where id = #{resourceId}
<if test="objectType != null and objectType == 'Project'">
select name from t_ds_project where id = #{objectId}
</if>
</select>
</mapper>

1
dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/AuditLogMapperTest.java

@ -17,7 +17,6 @@
package org.apache.dolphinscheduler.dao.mapper;
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
import org.apache.dolphinscheduler.dao.BaseDaoTest;
import org.apache.dolphinscheduler.dao.entity.AuditLog;
import org.apache.dolphinscheduler.dao.entity.Project;

1
dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessServiceImpl.java

@ -1911,6 +1911,7 @@ public class ProcessServiceImpl implements ProcessService {
if (Boolean.TRUE.equals(syncDefine)) {
if (processDefinition.getId() == null) {
result = processDefineMapper.insert(processDefinitionLog);
processDefinition.setId(processDefinitionLog.getId());
} else {
processDefinitionLog.setId(processDefinition.getId());
result = processDefineMapper.updateById(processDefinitionLog);

Loading…
Cancel
Save