Commit 7e7a7959 by lepdou

diff show deleted item & clogging

parent 76bd56d9
package com.ctrip.framework.apollo.biz.customize;
import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository;
import com.ctrip.framework.apollo.common.customize.LoggingCustomizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Component
@Profile("ctrip")
public class BizLoggingCustomizer extends LoggingCustomizer{
private static final String CLOGGING_SERVER_URL_KEY = "clogging.server.url";
private static final String CLOGGING_SERVER_PORT_KEY = "clogging.server.port";
@Autowired
private ServerConfigRepository serverConfigRepository;
private String cloggingUrl;
private String cloggingPort;
@Override
protected String cloggingUrl() {
if (cloggingUrl == null){
cloggingUrl = serverConfigRepository.findByKey(CLOGGING_SERVER_URL_KEY).getValue();
}
return cloggingUrl;
}
@Override
protected String cloggingPort() {
if (cloggingPort == null){
cloggingPort = serverConfigRepository.findByKey(CLOGGING_SERVER_PORT_KEY).getValue();
}
return cloggingPort;
}
}
/**
* 携程内部的日志系统,第三方公司可删除
*/
package com.ctrip.framework.apollo.biz.customize;
package com.ctrip.framework.apollo.biz.customize; package com.ctrip.framework.apollo.common.customize;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.ctrip.framework.apollo.biz.entity.ServerConfig;
import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository;
import com.ctrip.framework.foundation.Foundation; import com.ctrip.framework.foundation.Foundation;
import com.dianping.cat.Cat; import com.dianping.cat.Cat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import java.util.Objects;
import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.Appender; import ch.qos.logback.core.Appender;
/** /**
* clogging config.only used in ctrip
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
@Component public abstract class LoggingCustomizer implements InitializingBean {
public class LoggingCustomizer implements InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(LoggingCustomizer.class); private static final Logger logger = LoggerFactory.getLogger(LoggingCustomizer.class);
private static final String cLoggingAppenderClass = private static final String cLoggingAppenderClass =
"com.ctrip.framework.clogging.agent.appender.CLoggingAppender"; "com.ctrip.framework.clogging.agent.appender.CLoggingAppender";
private static boolean cLoggingAppenderPresent = private static boolean cLoggingAppenderPresent =
ClassUtils.isPresent(cLoggingAppenderClass, LoggingCustomizer.class.getClassLoader()); ClassUtils.isPresent(cLoggingAppenderClass, LoggingCustomizer.class.getClassLoader());
private static final String CLOGGING_SERVER_URL_KEY = "clogging.server.url";
private static final String CLOGGING_SERVER_PORT_KEY = "clogging.server.port";
@Autowired
private ServerConfigRepository serverConfigRepository;
@Override @Override
public void afterPropertiesSet() { public void afterPropertiesSet() {
if (!cLoggingAppenderPresent) { if (!cLoggingAppenderPresent) {
...@@ -59,13 +48,6 @@ public class LoggingCustomizer implements InitializingBean { ...@@ -59,13 +48,6 @@ public class LoggingCustomizer implements InitializingBean {
return; return;
} }
ServerConfig cloggingUrl = serverConfigRepository.findByKey(CLOGGING_SERVER_URL_KEY);
ServerConfig cloggingPort = serverConfigRepository.findByKey(CLOGGING_SERVER_PORT_KEY);
if (Objects.isNull(cloggingUrl) || Objects.isNull(cloggingPort)) {
logger.warn("CLogging config is not set!");
return;
}
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
Class clazz = Class.forName(cLoggingAppenderClass); Class clazz = Class.forName(cLoggingAppenderClass);
...@@ -73,9 +55,9 @@ public class LoggingCustomizer implements InitializingBean { ...@@ -73,9 +55,9 @@ public class LoggingCustomizer implements InitializingBean {
ReflectionUtils.findMethod(clazz, "setAppId", String.class).invoke(cLoggingAppender, appId); ReflectionUtils.findMethod(clazz, "setAppId", String.class).invoke(cLoggingAppender, appId);
ReflectionUtils.findMethod(clazz, "setServerIp", String.class) ReflectionUtils.findMethod(clazz, "setServerIp", String.class)
.invoke(cLoggingAppender, cloggingUrl.getValue()); .invoke(cLoggingAppender, cloggingUrl());
ReflectionUtils.findMethod(clazz, "setServerPort", int.class) ReflectionUtils.findMethod(clazz, "setServerPort", int.class)
.invoke(cLoggingAppender, Integer.parseInt(cloggingPort.getValue())); .invoke(cLoggingAppender, Integer.parseInt(cloggingPort()));
cLoggingAppender.setName("CentralLogging"); cLoggingAppender.setName("CentralLogging");
cLoggingAppender.setContext(loggerContext); cLoggingAppender.setContext(loggerContext);
...@@ -87,4 +69,17 @@ public class LoggingCustomizer implements InitializingBean { ...@@ -87,4 +69,17 @@ public class LoggingCustomizer implements InitializingBean {
} }
/**
* clogging server url
* @return
*/
protected abstract String cloggingUrl();
/**
* clogging server port
* @return
*/
protected abstract String cloggingPort();
} }
package com.ctrip.framework.apollo.biz.customize; package com.ctrip.framework.apollo.common.customize;
import org.apache.catalina.connector.Connector; import org.apache.catalina.connector.Connector;
import org.apache.coyote.ProtocolHandler; import org.apache.coyote.ProtocolHandler;
......
/**
* 携程内部的日志系统,第三方公司可删除
*/
package com.ctrip.framework.apollo.common.customize;
/**
* 携程内部的dal,第三方公司可替换实现
*/
package com.ctrip.framework.apollo.common.datasource;
...@@ -95,15 +95,20 @@ public class AdminServiceAPI { ...@@ -95,15 +95,20 @@ public class AdminServiceAPI {
@Service @Service
public static class ItemAPI extends API { public static class ItemAPI extends API {
public List<ItemDTO> findItems(String appId, Env env, String clusterName, String namespace) { public List<ItemDTO> findItems(String appId, Env env, String clusterName, String namespaceName) {
ItemDTO[] itemDTOs = ItemDTO[] itemDTOs =
restTemplate restTemplate
.getForObject("{host}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items", .getForObject("{host}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items",
ItemDTO[].class, ItemDTO[].class,
getAdminServiceHost(env), appId, clusterName, namespace); getAdminServiceHost(env), appId, clusterName, namespaceName);
return Arrays.asList(itemDTOs); return Arrays.asList(itemDTOs);
} }
public ItemDTO loadItem(String appId, Env env, String clusterName, String namespaceName, String key){
return restTemplate.getForObject("{host}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{key}",
ItemDTO.class, getAdminServiceHost(env), appId, clusterName, namespaceName, key);
}
public void updateItems(String appId, Env env, String clusterName, String namespace, public void updateItems(String appId, Env env, String clusterName, String namespace,
ItemChangeSets changeSets) { ItemChangeSets changeSets) {
restTemplate.postForEntity("{host}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/itemset", restTemplate.postForEntity("{host}/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/itemset",
......
package com.ctrip.framework.apollo.portal.cumsomize;
import com.ctrip.framework.apollo.common.customize.LoggingCustomizer;
import com.ctrip.framework.apollo.portal.repository.ServerConfigRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Component
@Profile("ctrip")
public class BizLoggingCustomizer extends LoggingCustomizer{
private static final String CLOGGING_SERVER_URL_KEY = "clogging.server.url";
private static final String CLOGGING_SERVER_PORT_KEY = "clogging.server.port";
@Autowired
private ServerConfigRepository serverConfigRepository;
private String cloggingUrl;
private String cloggingPort;
@Override
protected String cloggingUrl() {
if (cloggingUrl == null){
cloggingUrl = serverConfigRepository.findByKey(CLOGGING_SERVER_URL_KEY).getValue();
}
return cloggingUrl;
}
@Override
protected String cloggingPort() {
if (cloggingPort == null){
cloggingPort = serverConfigRepository.findByKey(CLOGGING_SERVER_PORT_KEY).getValue();
}
return cloggingPort;
}
}
/**
* 携程内部的日志系统,第三方公司可删除
*/
package com.ctrip.framework.apollo.portal.cumsomize;
...@@ -168,13 +168,14 @@ public class PortalConfigService { ...@@ -168,13 +168,14 @@ public class PortalConfigService {
namespace.getClusterName(), namespace.getNamespaceName()); namespace.getClusterName(), namespace.getNamespaceName());
long namespaceId = getNamespaceId(namespace); long namespaceId = getNamespaceId(namespace);
if (CollectionUtils.isEmpty(targetItems)) {//all source items is added if (CollectionUtils.isEmpty(targetItems)) {//all source items is added
int lineNum = 1; int lineNum = 1;
for (ItemDTO sourceItem : sourceItems) { for (ItemDTO sourceItem : sourceItems) {
changeSets.addCreateItem(buildItem(namespaceId, lineNum++, sourceItem)); changeSets.addCreateItem(buildItem(namespaceId, lineNum++, sourceItem));
} }
} else { } else {
Map<String, ItemDTO> keyMapItem = BeanUtils.mapByKey("key", targetItems); Map<String, ItemDTO> targetItemMap = BeanUtils.mapByKey("key", targetItems);
String key, sourceValue, sourceComment; String key, sourceValue, sourceComment;
ItemDTO targetItem = null; ItemDTO targetItem = null;
int maxLineNum = targetItems.size();//append to last int maxLineNum = targetItems.size();//append to last
...@@ -182,7 +183,7 @@ public class PortalConfigService { ...@@ -182,7 +183,7 @@ public class PortalConfigService {
key = sourceItem.getKey(); key = sourceItem.getKey();
sourceValue = sourceItem.getValue(); sourceValue = sourceItem.getValue();
sourceComment = sourceItem.getComment(); sourceComment = sourceItem.getComment();
targetItem = keyMapItem.get(key); targetItem = targetItemMap.get(key);
if (targetItem == null) {//added items if (targetItem == null) {//added items
...@@ -196,6 +197,16 @@ public class PortalConfigService { ...@@ -196,6 +197,16 @@ public class PortalConfigService {
} }
} }
//parse deleted items
List<ItemDTO> deletedItems = new LinkedList<>();
Map<String, ItemDTO> sourceItemMap = BeanUtils.mapByKey("key", sourceItems);
for (ItemDTO targetItem: targetItems){
if (sourceItemMap.get(targetItem.getKey()) == null){
deletedItems.add(targetItem);
}
}
changeSets.setDeleteItems(deletedItems);
return changeSets; return changeSets;
} }
......
...@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.portal.service; ...@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.portal.service;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.utils.ExceptionUtils; import com.ctrip.framework.apollo.common.utils.ExceptionUtils;
import com.ctrip.framework.apollo.core.dto.AppNamespaceDTO; import com.ctrip.framework.apollo.core.dto.AppNamespaceDTO;
import com.ctrip.framework.apollo.core.dto.ItemDTO; import com.ctrip.framework.apollo.core.dto.ItemDTO;
...@@ -139,17 +140,48 @@ public class PortalNamespaceService { ...@@ -139,17 +140,48 @@ public class PortalNamespaceService {
itemVos.add(itemVO); itemVos.add(itemVO);
} }
//count deleted item num
List<NamespaceVO.ItemVO> deletedItems = countDeletedItemNum(items, releaseItems);
itemVos.addAll(deletedItems);
modifiedItemCnt += deletedItems.size();
namespaceVO.setItemModifiedCnt(modifiedItemCnt); namespaceVO.setItemModifiedCnt(modifiedItemCnt);
return namespaceVO; return namespaceVO;
} }
private List<NamespaceVO.ItemVO> countDeletedItemNum(List<ItemDTO> newItems, Map<String, String> releaseItems) {
Map<String, ItemDTO> newItemMap = BeanUtils.mapByKey("key", newItems);
List<NamespaceVO.ItemVO> deletedItems = new LinkedList<>();
for (Map.Entry<String, String> entry: releaseItems.entrySet()){
String key = entry.getKey();
if (newItemMap.get(key) == null){
NamespaceVO.ItemVO deletedItem = new NamespaceVO.ItemVO();
ItemDTO deletedItemDto = new ItemDTO();
deletedItemDto.setKey(key);
String oldValue = entry.getValue();
deletedItem.setItem(deletedItemDto);
deletedItemDto.setValue(oldValue);
deletedItem.setModified(true);
deletedItem.setOldValue(oldValue);
deletedItem.setNewValue("");
deletedItems.add(deletedItem);
}
}
return deletedItems;
}
private NamespaceVO.ItemVO parseItemVO(ItemDTO itemDTO, Map<String, String> releaseItems) { private NamespaceVO.ItemVO parseItemVO(ItemDTO itemDTO, Map<String, String> releaseItems) {
String key = itemDTO.getKey(); String key = itemDTO.getKey();
NamespaceVO.ItemVO itemVO = new NamespaceVO.ItemVO(); NamespaceVO.ItemVO itemVO = new NamespaceVO.ItemVO();
itemVO.setItem(itemDTO); itemVO.setItem(itemDTO);
String newValue = itemDTO.getValue(); String newValue = itemDTO.getValue();
String oldValue = releaseItems.get(key); String oldValue = releaseItems.get(key);
//new item or modified
if (!StringUtils.isEmpty(key) && (oldValue == null || !newValue.equals(oldValue))) { if (!StringUtils.isEmpty(key) && (oldValue == null || !newValue.equals(oldValue))) {
itemVO.setModified(true); itemVO.setModified(true);
itemVO.setOldValue(oldValue == null ? "" : oldValue); itemVO.setOldValue(oldValue == null ? "" : oldValue);
......
...@@ -14,11 +14,7 @@ ...@@ -14,11 +14,7 @@
<apollonav></apollonav> <apollonav></apollonav>
<div class="container-fluid apollo-container"> <div class="container-fluid apollo-container app" id="config-info">
<div class="app">
<!--配置信息-->
<div id="config-info">
<!--具体配置信息--> <!--具体配置信息-->
<div class="row config-info-container"> <div class="row config-info-container">
...@@ -74,15 +70,15 @@ ...@@ -74,15 +70,15 @@
</div> </div>
</div> </div>
</a> </a>
<!--<a class="list-group-item" target="_blank" href="/views/config.html?#/appid={{app.appId}}">--> <a class="list-group-item" href="#" disabled="disabled" ng-show="false">
<!--<div class="row">--> <div class="row">
<!--<div class="col-md-2"><img src="../img/plus.png" class="i-20"></div>--> <div class="col-md-2"><img src="../img/plus.png" class="i-20"></div>
<!--<div class="col-md-7 hidden-xs">--> <div class="col-md-7 hidden-xs">
<!--<p class="apps-description">添加集群</p>--> <p class="btn-title">添加集群</p>
<!--</div>--> </div>
<!--</div>--> </div>
<!--</a>--> </a>
<a class="list-group-item" href="namespace.html?#/appid={{pageContext.appId}}&type=link"> <a class="list-group-item" href="namespace.html?#/appid={{pageContext.appId}}&type=link">
<div class="row"> <div class="row">
<div class="col-md-2"><img src="img/plus.png" class="i-20"></div> <div class="col-md-2"><img src="img/plus.png" class="i-20"></div>
...@@ -147,14 +143,13 @@ ...@@ -147,14 +143,13 @@
ng-click="prepareReleaseNamespace(namespace)">发布 ng-click="prepareReleaseNamespace(namespace)">发布
</button> </button>
<button type="button" <button type="button"
class="btn btn-default btn-sm J_tableview_btn">回滚 class="btn btn-default btn-sm J_tableview_btn" disabled>回滚
</button> </button>
<button type="button" <button type="button"
class="btn btn-default btn-sm J_historyview_btn"> class="btn btn-default btn-sm J_historyview_btn" disabled>查看历史版本
查看历史版本
</button> </button>
<button type="button" <button type="button"
class="btn btn-default btn-sm J_tableview_btn">授权 class="btn btn-default btn-sm J_tableview_btn" disabled>授权
</button> </button>
<a type="button" <a type="button"
href="config/sync.html?#/appid={{pageContext.appId}}&env={{pageContext.env}}&clusterName={{pageContext.clusterName}}&namespaceName={{namespace.namespace.namespaceName}}" href="config/sync.html?#/appid={{pageContext.appId}}&env={{pageContext.env}}&clusterName={{pageContext.clusterName}}&namespaceName={{namespace.namespace.namespaceName}}"
...@@ -177,7 +172,7 @@ ...@@ -177,7 +172,7 @@
</button> </button>
<button type="button" <button type="button"
class="btn btn-default btn-sm J_historyview_btn" class="btn btn-default btn-sm J_historyview_btn"
ng-click="switchView(namespace, 'history')"> ng-click="switchView(namespace, 'history')" disabled>
更改历史 更改历史
</button> </button>
</div> </div>
...@@ -255,7 +250,7 @@ ...@@ -255,7 +250,7 @@
<tbody> <tbody>
<tr ng-repeat="config in namespace.items" ng-class="{warning:config.isModified}" <tr ng-repeat="config in namespace.items" ng-class="{warning:config.isModified}"
ng-if="config.item.key"> ng-if="config.item.key && config.item.lastModifiedBy">
<td width="20%" title="{{config.item.key}}"> <td width="20%" title="{{config.item.key}}">
<span ng-bind="config.item.key | limitTo: 250"></span> <span ng-bind="config.item.key | limitTo: 250"></span>
<span ng-bind="config.item.key.length > 250 ? '...' :''"></span> <span ng-bind="config.item.key.length > 250 ? '...' :''"></span>
...@@ -435,6 +430,8 @@ ...@@ -435,6 +430,8 @@
<tr ng-repeat="config in toReleaseNamespace.items" <tr ng-repeat="config in toReleaseNamespace.items"
ng-if="config.item.key && config.isModified"> ng-if="config.item.key && config.isModified">
<td width="20%" title="{{config.item.key}}"> <td width="20%" title="{{config.item.key}}">
<span class="label label-danger"
ng-show="!config.newValue">deleted</span>
<span ng-bind="config.item.key | limitTo: 250"></span> <span ng-bind="config.item.key | limitTo: 250"></span>
<span ng-bind="config.item.key.length > 250 ? '...' :''"></span> <span ng-bind="config.item.key.length > 250 ? '...' :''"></span>
</td> </td>
...@@ -442,9 +439,9 @@ ...@@ -442,9 +439,9 @@
<span ng-bind="config.oldValue | limitTo: 250"></span> <span ng-bind="config.oldValue | limitTo: 250"></span>
<span ng-bind="config.oldValue.length > 250 ? '...': ''"></span> <span ng-bind="config.oldValue.length > 250 ? '...': ''"></span>
</td> </td>
<td width="25%" title="{{config.item.value}}"> <td width="25%" title="{{config.newValue}}">
<span ng-bind="config.item.value | limitTo: 250"></span> <span ng-bind="config.newValue | limitTo: 250"></span>
<span ng-bind="config.item.value.length > 250 ? '...': ''"></span> <span ng-bind="config.newValue.length > 250 ? '...': ''"></span>
</td> </td>
<td width="15%" ng-bind="config.item.lastModifiedBy"> <td width="15%" ng-bind="config.item.lastModifiedBy">
</td> </td>
...@@ -572,10 +569,8 @@ ...@@ -572,10 +569,8 @@
</form> </form>
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
......
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
<script type="application/javascript" src="scripts/services/AppService.js"></script> <script type="application/javascript" src="scripts/services/AppService.js"></script>
<script type="application/javascript" src="scripts/services/EnvService.js"></script> <script type="application/javascript" src="scripts/services/EnvService.js"></script>
<script type="application/javascript" src="scripts/services/UserService.js"></script>
<script type="application/javascript" src="scripts/services/ServerConfigService.js"></script> <script type="application/javascript" src="scripts/services/ServerConfigService.js"></script>
<script type="application/javascript" src="scripts/controller/ServerConfigController.js"></script> <script type="application/javascript" src="scripts/controller/ServerConfigController.js"></script>
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li><a href="http://conf.ctripcorp.com/pages/viewpage.action?pageId=98435462" target="_blank">
help</span>
</a></li>
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">{{userName}} <span class="caret"></span></a> aria-expanded="false">{{userName}} <span class="caret"></span></a>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment