You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by xi...@apache.org on 2022/06/01 02:25:37 UTC

[incubator-shenyu] branch master updated: [ISSUE #3221]Record log meta data (#3462)

This is an automated email from the ASF dual-hosted git repository.

xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new a8d8407db [ISSUE #3221]Record log meta data (#3462)
a8d8407db is described below

commit a8d8407dbdef7a0e8e09b135971efe546933e373
Author: likeguo <33...@users.noreply.github.com>
AuthorDate: Wed Jun 1 10:25:29 2022 +0800

    [ISSUE #3221]Record log meta data (#3462)
    
    * fixbug/pg script error
    
    * feature/record log in meta data
    
    * feature/record log in meta data
---
 .../shenyu/admin/model/enums/EventTypeEnum.java    |  17 +++-
 .../event/metadata/BatchMetaDataChangedEvent.java  |  58 ++++++++++++
 .../event/metadata/BatchMetaDataDeletedEvent.java  |  65 +++++++++++++
 .../model/event/metadata/MetaDataChangedEvent.java | 100 ++++++++++++++++++++
 .../model/event/metadata/MetaDataCreatedEvent.java |  48 ++++++++++
 .../model/event/metadata/MetadataUpdatedEvent.java |  49 ++++++++++
 .../admin/service/impl/MetaDataServiceImpl.java    |  70 +++++++-------
 .../service/publish/MetaDataEventPublisher.java    | 101 +++++++++++++++++++++
 .../shenyu/admin/service/MetaDataServiceTest.java  |   4 +
 9 files changed, 475 insertions(+), 37 deletions(-)

diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/enums/EventTypeEnum.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/enums/EventTypeEnum.java
index 73c416a7e..9a8938b6b 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/enums/EventTypeEnum.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/enums/EventTypeEnum.java
@@ -55,6 +55,11 @@ public enum EventTypeEnum {
      */
     RULE_CREATE("CREATE:RULE", DataEventTypeEnum.CREATE, Color.CREATE_COLOR),
     
+    /**
+     * meta data created event.
+     */
+    META_DATA_CREATE("CREATE:META_DATA", DataEventTypeEnum.CREATE, Color.CREATE_COLOR),
+    
     /**
      * resource created event.
      */
@@ -92,6 +97,11 @@ public enum EventTypeEnum {
      */
     RULE_DELETE("DELETE:RULE", DataEventTypeEnum.DELETE, Color.DELETE_COLOR),
     
+    /**
+     * meta data deleted event.
+     */
+    META_DATA_DELETE("DELETE:META_DATA", DataEventTypeEnum.DELETE, Color.DELETE_COLOR),
+    
     /**
      * resource deleted event.
      */
@@ -124,6 +134,11 @@ public enum EventTypeEnum {
      */
     RULE_UPDATE("UPDATE:RULE", DataEventTypeEnum.UPDATE, Color.UPDATE_COLOR),
     
+    /**
+     * meta data update.
+     */
+    META_DATA_UPDATE("UPDATE:META_DATA", DataEventTypeEnum.UPDATE, Color.UPDATE_COLOR),
+    
     /**
      * resource update.
      */
@@ -199,7 +214,7 @@ public enum EventTypeEnum {
         /**
          * default update event color.
          */
-        public static final String UPDATE_COLOR = "yellow";
+        public static final String UPDATE_COLOR = "#CC6600";
     }
     
 }
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/BatchMetaDataChangedEvent.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/BatchMetaDataChangedEvent.java
new file mode 100644
index 000000000..91f8b9b36
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/BatchMetaDataChangedEvent.java
@@ -0,0 +1,58 @@
+/*
+ * 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.shenyu.admin.model.event.metadata;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.entity.MetaDataDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+import org.apache.shenyu.admin.model.event.BatchChangedEvent;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * BatchMetaDataChangedEvent.
+ */
+public class BatchMetaDataChangedEvent extends BatchChangedEvent {
+    
+    
+    /**
+     * Create a new {@code BatchMetaDataChangedEvent}.operator is unknown.
+     *
+     * @param source Current metadata state
+     * @param before Before the change metadata state
+     * @param type   event type
+     */
+    public BatchMetaDataChangedEvent(final Collection<MetaDataDO> source, final Collection<MetaDataDO> before, final EventTypeEnum type, final String operator) {
+        super(source, before, type, operator);
+    }
+    
+    @Override
+    public String buildContext() {
+        final String metadata = ((Collection<?>) getSource())
+                .stream()
+                .map(s -> ((MetaDataDO) s).getAppName())
+                .collect(Collectors.joining(","));
+        return String.format("the meta data [%s] is %s", metadata, StringUtils.lowerCase(getType().getType().toString()));
+    }
+    
+    @Override
+    public String eventName() {
+        return "meta data";
+    }
+}
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/BatchMetaDataDeletedEvent.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/BatchMetaDataDeletedEvent.java
new file mode 100644
index 000000000..ce65263ae
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/BatchMetaDataDeletedEvent.java
@@ -0,0 +1,65 @@
+/*
+ * 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.shenyu.admin.model.event.metadata;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.entity.BaseDO;
+import org.apache.shenyu.admin.model.entity.MetaDataDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+import org.apache.shenyu.admin.utils.ListUtil;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * BatchMetaDataDeletedEvent.
+ */
+public class BatchMetaDataDeletedEvent extends BatchMetaDataChangedEvent {
+    
+    private final List<String> deletedIds;
+    
+    /**
+     * Create a new {@code BatchMetaDataDeletedEvent}.operator is unknown.
+     *
+     * @param source   Current metadata state
+     * @param operator operator
+     */
+    public BatchMetaDataDeletedEvent(final Collection<MetaDataDO> source, final String operator) {
+        super(source, null, EventTypeEnum.META_DATA_DELETE, operator);
+        this.deletedIds = ListUtil.map(source, BaseDO::getId);
+    }
+    
+    @Override
+    public String buildContext() {
+        final String metaData = ((Collection<?>) getSource())
+                .stream()
+                .map(s -> ((MetaDataDO) s).getAppName())
+                .collect(Collectors.joining(","));
+        return String.format("the meta data[%s] is %s", metaData, StringUtils.lowerCase(getType().getType().toString()));
+    }
+    
+    /**
+     * get deleted iss.
+     *
+     * @return list
+     */
+    public List<String> getDeletedIds() {
+        return deletedIds;
+    }
+}
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/MetaDataChangedEvent.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/MetaDataChangedEvent.java
new file mode 100644
index 000000000..11da20b0c
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/MetaDataChangedEvent.java
@@ -0,0 +1,100 @@
+/*
+ * 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.shenyu.admin.model.event.metadata;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.entity.MetaDataDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+import org.apache.shenyu.admin.model.event.AdminDataModelChangedEvent;
+
+import java.util.Objects;
+
+/**
+ * MetaDatarChangedEvent.
+ */
+public class MetaDataChangedEvent extends AdminDataModelChangedEvent {
+    
+    
+    /**
+     * Create a new {@code PluginChangedEvent}.operator is unknown.
+     *
+     * @param source Current plugin state
+     * @param before Before the change plugiin state
+     * @param type   event type
+     */
+    public MetaDataChangedEvent(final MetaDataDO source, final MetaDataDO before, final EventTypeEnum type, final String operator) {
+        super(source, before, type, operator);
+    }
+    
+    @Override
+    public String buildContext() {
+        final MetaDataDO after = (MetaDataDO) getAfter();
+        if (Objects.isNull(getBefore())) {
+            return String.format("the metadata [%s %s] is %s", after.getAppName(), after.getPath(), StringUtils.lowerCase(getType().getType().toString()));
+        }
+        return String.format("the metadata [%s %s] is %s : %s", after.getAppName(), after.getPath(), StringUtils.lowerCase(getType().getType().toString()), contrast());
+        
+    }
+    
+    private String contrast() {
+        final MetaDataDO before = (MetaDataDO) getBefore();
+        Objects.requireNonNull(before);
+        final MetaDataDO after = (MetaDataDO) getAfter();
+        Objects.requireNonNull(after);
+        if (Objects.equals(before, after)) {
+            return "it no change";
+        }
+        final StringBuilder builder = new StringBuilder();
+        if (!Objects.equals(before.getAppName(), after.getAppName())) {
+            builder.append(String.format("appName[%s => %s] ", before.getAppName(), after.getAppName()));
+        }
+        if (!Objects.equals(before.getPath(), after.getPath())) {
+            builder.append(String.format("path[%s => %s] ", before.getPath(), after.getPath()));
+        }
+        if (!Objects.equals(before.getPathDesc(), after.getPathDesc())) {
+            builder.append(String.format("path desc[%s => %s] ", before.getPathDesc(), after.getPathDesc()));
+        }
+        if (!Objects.equals(before.getEnabled(), after.getEnabled())) {
+            builder.append(String.format("enable[%s => %s] ", before.getEnabled(), after.getEnabled()));
+        }
+        if (!Objects.equals(before.getServiceName(), after.getServiceName())) {
+            builder.append(String.format("service[%s => %s] ", before.getServiceName(), after.getServiceName()));
+        }
+        if (!Objects.equals(before.getMethodName(), after.getMethodName())) {
+            builder.append(String.format("method[%s => %s] ", before.getMethodName(), after.getMethodName()));
+        }
+        if (!Objects.equals(before.getParameterTypes(), after.getParameterTypes())) {
+            builder.append(String.format("parameter type [%s => %s] ", before.getParameterTypes(), after.getParameterTypes()));
+        }
+        if (!Objects.equals(before.getEnabled(), after.getEnabled())) {
+            builder.append(String.format("enable [%s => %s] ", before.getEnabled(), after.getEnabled()));
+        }
+        if (!Objects.equals(before.getRpcType(), after.getRpcType())) {
+            builder.append(String.format("rpc type [%s => %s] ", before.getRpcType(), after.getRpcType()));
+        }
+        if (!Objects.equals(before.getRpcExt(), after.getRpcExt())) {
+            builder.append(String.format("rpc ext [%s => %s] ", before.getRpcExt(), after.getRpcExt()));
+        }
+        return builder.toString();
+    }
+    
+    @Override
+    public String eventName() {
+        return "meta data";
+    }
+}
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/MetaDataCreatedEvent.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/MetaDataCreatedEvent.java
new file mode 100644
index 000000000..32ed811e5
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/MetaDataCreatedEvent.java
@@ -0,0 +1,48 @@
+/*
+ * 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.shenyu.admin.model.event.metadata;
+
+import org.apache.shenyu.admin.model.entity.MetaDataDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+
+/**
+ * MetaDataCreatedEvent.
+ */
+public class MetaDataCreatedEvent extends MetaDataChangedEvent {
+    
+    
+    /**
+     * Create a new {@code MetaDataChangedEvent}.operator is unknown.
+     *
+     * @param source   Current metadata state
+     * @param operator operator
+     */
+    public MetaDataCreatedEvent(final MetaDataDO source, final String operator) {
+        super(source, null, EventTypeEnum.META_DATA_CREATE, operator);
+    }
+    
+    /**
+     * the created metadata.
+     *
+     * @return metadata
+     */
+    public MetaDataDO getMetaData() {
+        return (MetaDataDO) getSource();
+    }
+    
+}
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/MetadataUpdatedEvent.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/MetadataUpdatedEvent.java
new file mode 100644
index 000000000..4807d6830
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/metadata/MetadataUpdatedEvent.java
@@ -0,0 +1,49 @@
+/*
+ * 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.shenyu.admin.model.event.metadata;
+
+import org.apache.shenyu.admin.model.entity.MetaDataDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+
+/**
+ * MetadataUpdatedEvent.
+ */
+public class MetadataUpdatedEvent extends MetaDataChangedEvent {
+    
+    
+    /**
+     * Create a new {@code SelectorChangedEvent}.operator is unknown.
+     *
+     * @param source   Current selector state
+     * @param before   before selector state
+     * @param operator operator
+     */
+    public MetadataUpdatedEvent(final MetaDataDO source, final MetaDataDO before, final String operator) {
+        super(source, before, EventTypeEnum.META_DATA_UPDATE, operator);
+    }
+    
+    /**
+     * the created metadata.
+     *
+     * @return metadata
+     */
+    public MetaDataDO getMetaData() {
+        return (MetaDataDO) getSource();
+    }
+    
+}
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/MetaDataServiceImpl.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/MetaDataServiceImpl.java
index a5f46977d..be1a63641 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/MetaDataServiceImpl.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/MetaDataServiceImpl.java
@@ -29,8 +29,10 @@ import org.apache.shenyu.admin.model.page.PageResultUtils;
 import org.apache.shenyu.admin.model.query.MetaDataQuery;
 import org.apache.shenyu.admin.model.vo.MetaDataVO;
 import org.apache.shenyu.admin.service.MetaDataService;
+import org.apache.shenyu.admin.service.publish.MetaDataEventPublisher;
 import org.apache.shenyu.admin.transfer.MetaDataTransfer;
 import org.apache.shenyu.admin.utils.Assert;
+import org.apache.shenyu.admin.utils.ListUtil;
 import org.apache.shenyu.admin.utils.ShenyuResultMessage;
 import org.apache.shenyu.common.constant.AdminConstants;
 import org.apache.shenyu.common.dto.MetaData;
@@ -59,9 +61,14 @@ public class MetaDataServiceImpl implements MetaDataService {
     
     private final ApplicationEventPublisher eventPublisher;
     
-    public MetaDataServiceImpl(final MetaDataMapper metaDataMapper, final ApplicationEventPublisher eventPublisher) {
+    private final MetaDataEventPublisher publisher;
+    
+    public MetaDataServiceImpl(final MetaDataMapper metaDataMapper,
+                               final ApplicationEventPublisher eventPublisher,
+                               final MetaDataEventPublisher publisher) {
         this.metaDataMapper = metaDataMapper;
         this.eventPublisher = eventPublisher;
+        this.publisher = publisher;
     }
     
     @Override
@@ -92,37 +99,29 @@ public class MetaDataServiceImpl implements MetaDataService {
     
     @Override
     public int delete(final List<String> ids) {
-        List<String> distinctIds = ids.stream().distinct().collect(Collectors.toList());
-        List<MetaDataDO> metaDataDoList = metaDataMapper.selectByIdList(distinctIds);
-        if (CollectionUtils.isEmpty(metaDataDoList)) {
+        List<MetaDataDO> deletedMetaData = metaDataMapper.selectByIdList(ids);
+        if (CollectionUtils.isEmpty(deletedMetaData)) {
             return 0;
         }
-        List<MetaData> metaDataList = metaDataDoList
-                .stream().map(MetaDataTransfer.INSTANCE::mapToData).collect(Collectors.toList());
-            
-        int count = metaDataMapper.deleteByIdList(distinctIds);
-        eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.META_DATA, DataEventTypeEnum.DELETE, metaDataList));
-
+        int count = metaDataMapper.deleteByIdList(ids);
+        if (count > 0) {
+            publisher.onDeleted(deletedMetaData);
+        }
         return count;
     }
     
     @Override
     public String enabled(final List<String> ids, final Boolean enabled) {
-        List<String> distinctIds = ids.stream().distinct().collect(Collectors.toList());
-        List<MetaDataDO> metaDataDoList = metaDataMapper.selectByIdList(distinctIds);
+        List<MetaDataDO> metaDataDoList = metaDataMapper.selectByIdList(ids);
         if (CollectionUtils.isEmpty(metaDataDoList)) {
             return AdminConstants.ID_NOT_EXIST;
         }
-        List<MetaData> metaDataList = metaDataDoList.stream()
-            .map(metaDataDo -> {
-                metaDataDo.setEnabled(enabled);
-                return MetaDataTransfer.INSTANCE.mapToData(metaDataDo);
-            }).collect(Collectors.toList());
-        metaDataMapper.updateEnableBatch(distinctIds, enabled);
-        
-        eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.META_DATA, DataEventTypeEnum.UPDATE,
-            metaDataList));
-        
+        for (MetaDataDO metaDataDO : metaDataDoList) {
+            metaDataDO.setEnabled(enabled);
+        }
+        if (metaDataMapper.updateEnableBatch(ids, enabled) > 0) {
+            publisher.onEnabled(metaDataDoList);
+        }
         return StringUtils.EMPTY;
     }
     
@@ -155,18 +154,12 @@ public class MetaDataServiceImpl implements MetaDataService {
     
     @Override
     public Map<String, List<MetaDataVO>> findAllGroup() {
-        return MetaDataTransfer.INSTANCE.mapToVOList(metaDataMapper.selectAll())
-                .stream()
-                .collect(Collectors.groupingBy(MetaDataVO::getAppName));
+        return ListUtil.groupBy(findAll(), MetaDataVO::getAppName);
     }
     
     @Override
     public List<MetaData> listAll() {
-        return metaDataMapper.selectAll()
-                .stream()
-                .filter(Objects::nonNull)
-                .map(MetaDataTransfer.INSTANCE::mapToData)
-                .collect(Collectors.toList());
+        return ListUtil.map(metaDataMapper.selectAll(), MetaDataTransfer.INSTANCE::mapToData);
     }
     
     @Override
@@ -183,7 +176,7 @@ public class MetaDataServiceImpl implements MetaDataService {
     public int insert(final MetaDataDO metaDataDO) {
         return metaDataMapper.insert(metaDataDO);
     }
-
+    
     private String create(final MetaDataDTO metaDataDTO) {
         Assert.isNull(metaDataMapper.pathExisted(metaDataDTO.getPath()), AdminConstants.DATA_PATH_IS_EXIST);
         MetaDataDO metaDataDO = MetaDataTransfer.INSTANCE.mapToEntity(metaDataDTO);
@@ -192,22 +185,27 @@ public class MetaDataServiceImpl implements MetaDataService {
         Timestamp currentTime = new Timestamp(System.currentTimeMillis());
         metaDataDO.setDateCreated(currentTime);
         metaDataDO.setDateUpdated(currentTime);
-        metaDataMapper.insert(metaDataDO);
-
+        if (metaDataMapper.insert(metaDataDO) > 0) {
+            publisher.onCreated(metaDataDO);
+        }
+        
         // publish AppAuthData's creste event
         eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.META_DATA, DataEventTypeEnum.CREATE,
                 Collections.singletonList(MetaDataTransfer.INSTANCE.mapToData(metaDataDTO))));
         return ShenyuResultMessage.CREATE_SUCCESS;
     }
-
+    
     private String update(final MetaDataDTO metaDataDTO) {
         Assert.isNull(metaDataMapper.pathExistedExclude(metaDataDTO.getPath(), Collections.singletonList(metaDataDTO.getId())), AdminConstants.DATA_PATH_IS_EXIST);
         MetaDataDO metaDataDO = MetaDataTransfer.INSTANCE.mapToEntity(metaDataDTO);
         Optional.ofNullable(metaDataMapper.selectById(metaDataDTO.getId()))
                 .ifPresent(e -> metaDataDTO.setEnabled(e.getEnabled()));
         metaDataDO.setPathDesc(Objects.isNull(metaDataDO.getPathDesc()) ? "" : metaDataDO.getPathDesc());
-        metaDataMapper.update(metaDataDO);
-
+        final MetaDataDO before = metaDataMapper.selectById(metaDataDO.getId());
+        if (metaDataMapper.update(metaDataDO) > 0) {
+            publisher.onUpdated(metaDataDO, before);
+        }
+        
         // publish AppAuthData's update event
         eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.META_DATA, DataEventTypeEnum.UPDATE,
                 Collections.singletonList(MetaDataTransfer.INSTANCE.mapToData(metaDataDTO))));
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/publish/MetaDataEventPublisher.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/publish/MetaDataEventPublisher.java
new file mode 100644
index 000000000..f06d1fcc7
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/publish/MetaDataEventPublisher.java
@@ -0,0 +1,101 @@
+/*
+ * 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.shenyu.admin.service.publish;
+
+import org.apache.shenyu.admin.listener.DataChangedEvent;
+import org.apache.shenyu.admin.model.entity.MetaDataDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+import org.apache.shenyu.admin.model.event.AdminDataModelChangedEvent;
+import org.apache.shenyu.admin.model.event.metadata.BatchMetaDataChangedEvent;
+import org.apache.shenyu.admin.model.event.metadata.BatchMetaDataDeletedEvent;
+import org.apache.shenyu.admin.model.event.metadata.MetaDataCreatedEvent;
+import org.apache.shenyu.admin.model.event.metadata.MetadataUpdatedEvent;
+import org.apache.shenyu.admin.transfer.MetaDataTransfer;
+import org.apache.shenyu.admin.utils.ListUtil;
+import org.apache.shenyu.admin.utils.SessionUtil;
+import org.apache.shenyu.common.enums.ConfigGroupEnum;
+import org.apache.shenyu.common.enums.DataEventTypeEnum;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+
+/**
+ * MetaDataEventPublisher.
+ */
+@Component
+public class MetaDataEventPublisher implements AdminDataModelChangedEventPublisher<MetaDataDO> {
+    
+    private final ApplicationEventPublisher publisher;
+    
+    public MetaDataEventPublisher(final ApplicationEventPublisher publisher) {
+        this.publisher = publisher;
+    }
+    
+    /**
+     * on selector created.
+     *
+     * @param selector selector
+     */
+    @Override
+    public void onCreated(final MetaDataDO selector) {
+        publish(new MetaDataCreatedEvent(selector, SessionUtil.visitorName()));
+    }
+    
+    /**
+     * on selector updated.
+     *
+     * @param selector selector
+     * @param before   before selector
+     */
+    @Override
+    public void onUpdated(final MetaDataDO selector, final MetaDataDO before) {
+        publish(new MetadataUpdatedEvent(selector, before, SessionUtil.visitorName()));
+    }
+    
+    /**
+     * on data deleted.
+     *
+     * @param data data
+     */
+    @Override
+    public void onDeleted(final Collection<MetaDataDO> data) {
+        publish(new BatchMetaDataDeletedEvent(data, SessionUtil.visitorName()));
+        publisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.META_DATA, DataEventTypeEnum.DELETE, ListUtil.map(data, MetaDataTransfer.INSTANCE::mapToData)));
+    }
+    
+    /**
+     * on metaData batch enabled.
+     *
+     * @param metaData metaData
+     */
+    public void onEnabled(final Collection<MetaDataDO> metaData) {
+        publish(new BatchMetaDataChangedEvent(metaData, null, EventTypeEnum.META_DATA_UPDATE, SessionUtil.visitorName()));
+        publisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.META_DATA, DataEventTypeEnum.UPDATE, ListUtil.map(metaData, MetaDataTransfer.INSTANCE::mapToData)));
+    }
+    
+    /**
+     * event.
+     *
+     * @param event event.
+     */
+    @Override
+    public void publish(final AdminDataModelChangedEvent event) {
+        publisher.publishEvent(event);
+    }
+}
diff --git a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/MetaDataServiceTest.java b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/MetaDataServiceTest.java
index ada7039b9..0df04979e 100644
--- a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/MetaDataServiceTest.java
+++ b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/MetaDataServiceTest.java
@@ -27,6 +27,7 @@ import org.apache.shenyu.admin.model.page.PageParameter;
 import org.apache.shenyu.admin.model.query.MetaDataQuery;
 import org.apache.shenyu.admin.model.vo.MetaDataVO;
 import org.apache.shenyu.admin.service.impl.MetaDataServiceImpl;
+import org.apache.shenyu.admin.service.publish.MetaDataEventPublisher;
 import org.apache.shenyu.admin.utils.ShenyuResultMessage;
 import org.apache.shenyu.common.constant.AdminConstants;
 import org.apache.shenyu.common.dto.MetaData;
@@ -77,6 +78,9 @@ public final class MetaDataServiceTest {
 
     @Mock
     private ApplicationEventPublisher eventPublisher;
+    
+    @Mock
+    private MetaDataEventPublisher publisher;
 
     @Mock
     private MetaDataDTO metaDataDTO;