##### Coverage Report - com.ctrip.framework.apollo.internals.AbstractConfig

Classes in this File | Line Coverage | Branch Coverage | Complexity
AbstractConfig |
64% | 34/53
37% | 12/32
| 2.4166666666666665;2.417
AbstractConfig$1 |
66% | 8/12
N/A | N/A
| 2.4166666666666665;2.417

1 |  |
     package com.ctrip.framework.apollo.internals;
2 |  |
3 |  |
     import com.google.common.base.Objects;
4 |  |
     import com.google.common.collect.Lists;
5 |  |
     import com.google.common.collect.Sets;
6 |  |
7 |  |
     import com.ctrip.framework.apollo.Config;
8 |  |
     import com.ctrip.framework.apollo.ConfigChangeListener;
9 |  |
     import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
10 |  |
     import com.ctrip.framework.apollo.enums.PropertyChangeType;
11 |  |
     import com.ctrip.framework.apollo.model.ConfigChange;
12 |  |
     import com.ctrip.framework.apollo.model.ConfigChangeEvent;
13 |  |
     import com.dianping.cat.Cat;
14 |  |
     import com.dianping.cat.message.Message;
15 |  |
     import com.dianping.cat.message.Transaction;
16 |  |
17 |  |
     import org.slf4j.Logger;
18 |  |
     import org.slf4j.LoggerFactory;
19 |  |
20 |  |
     import java.util.List;
21 |  |
     import java.util.Properties;
22 |  |
     import java.util.Set;
23 |  |
     import java.util.concurrent.ExecutorService;
24 |  |
     import java.util.concurrent.Executors;
25 |  |
26 |  |
     /**
27 |  |
      * @author Jason Song(song_s@ctrip.com)
28 |  |
      */
29 | 20 |
     public abstract class AbstractConfig implements Config {
30 | 1 |
       private static final Logger logger = LoggerFactory.getLogger(AbstractConfig.class);
31 |  |
       private static ExecutorService m_executorService;
32 | 20 |
       private List<ConfigChangeListener> m_listeners = Lists.newCopyOnWriteArrayList();
33 |  |
34 |  |
       static {
35 | 2 |
         m_executorService = Executors.newCachedThreadPool(ApolloThreadFactory
36 | 1 |
             .create("Config", true));
37 |  |
38 | 1 |
       }
39 |  |
40 |  |
       @Override
41 |  |
       public void addChangeListener(ConfigChangeListener listener) {
42 | 4 |
         if (!m_listeners.contains(listener)) {
43 | 4 |
           m_listeners.add(listener);
44 |  |
         }
45 | 4 |
       }
46 |  |
47 |  |
       @Override
48 |  |
       public Integer getIntProperty(String key, Integer defaultValue) {
49 | 0 |
         String value = getProperty(key, null);
50 | 0 |
         return value == null ? defaultValue : Integer.parseInt(value);
51 |  |
       }
52 |  |
53 |  |
       @Override
54 |  |
       public Long getLongProperty(String key, Long defaultValue) {
55 | 0 |
         String value = getProperty(key, null);
56 | 0 |
         return value == null ? defaultValue : Long.parseLong(value);
57 |  |
       }
58 |  |
59 |  |
       @Override
60 |  |
       public Short getShortProperty(String key, Short defaultValue) {
61 | 0 |
         String value = getProperty(key, null);
62 | 0 |
         return value == null ? defaultValue : Short.parseShort(value);
63 |  |
       }
64 |  |
65 |  |
       @Override
66 |  |
       public Float getFloatProperty(String key, Float defaultValue) {
67 | 0 |
         String value = getProperty(key, null);
68 | 0 |
         return value == null ? defaultValue : Float.parseFloat(value);
69 |  |
       }
70 |  |
71 |  |
       @Override
72 |  |
       public Double getDoubleProperty(String key, Double defaultValue) {
73 | 0 |
         String value = getProperty(key, null);
74 | 0 |
         return value == null ? defaultValue : Double.parseDouble(value);
75 |  |
       }
76 |  |
77 |  |
       @Override
78 |  |
       public Byte getByteProperty(String key, Byte defaultValue) {
79 | 0 |
         String value = getProperty(key, null);
80 | 0 |
         return value == null ? defaultValue : Byte.parseByte(value);
81 |  |
       }
82 |  |
83 |  |
       @Override
84 |  |
       public Boolean getBooleanProperty(String key, Boolean defaultValue) {
85 | 0 |
         String value = getProperty(key, null);
86 | 0 |
         return value == null ? defaultValue : Boolean.parseBoolean(value);
87 |  |
       }
88 |  |
89 |  |
       @Override
90 |  |
       public String[] getArrayProperty(String key, String delimiter, String[] defaultValue) {
91 | 0 |
         String value = getProperty(key, null);
92 | 0 |
         return value == null ? defaultValue : value.split(delimiter);
93 |  |
       }
94 |  |
95 |  |
       protected void fireConfigChange(final ConfigChangeEvent changeEvent) {
96 | 5 |
         for (final ConfigChangeListener listener : m_listeners) {
97 | 5 |
           m_executorService.submit(new Runnable() {
98 |  |
             @Override
99 |  |
             public void run() {
100 | 5 |
               String listenerName = listener.getClass().getName();
101 | 5 |
               Transaction transaction = Cat.newTransaction("Apollo.ConfigChangeListener", listenerName);
102 |  |
               try {
103 | 5 |
                 listener.onChange(changeEvent);
104 | 5 |
                 transaction.setStatus(Message.SUCCESS);
105 | 0 |
               } catch (Throwable ex) {
106 | 0 |
                 transaction.setStatus(ex);
107 | 0 |
                 Cat.logError(ex);
108 | 0 |
                 logger.error("Failed to invoke config change listener {}", listenerName, ex);
109 |  |
               } finally {
110 | 5 |
                 transaction.complete();
111 | 5 |
               }
112 | 5 |
             }
113 |  |
           });
114 | 5 |
         }
115 | 5 |
       }
116 |  |
117 |  |
       List<ConfigChange> calcPropertyChanges(String namespace, Properties previous,
118 |  |
                                              Properties current) {
119 | 5 |
         if (previous == null) {
120 | 0 |
           previous = new Properties();
121 |  |
         }
122 |  |
123 | 5 |
         if (current == null) {
124 | 0 |
           current = new Properties();
125 |  |
         }
126 |  |
127 | 5 |
         Set<String> previousKeys = previous.stringPropertyNames();
128 | 5 |
         Set<String> currentKeys = current.stringPropertyNames();
129 |  |
130 | 5 |
         Set<String> commonKeys = Sets.intersection(previousKeys, currentKeys);
131 | 5 |
         Set<String> newKeys = Sets.difference(currentKeys, commonKeys);
132 | 5 |
         Set<String> removedKeys = Sets.difference(previousKeys, commonKeys);
133 |  |
134 | 5 |
         List<ConfigChange> changes = Lists.newArrayList();
135 |  |
136 | 5 |
         for (String newKey : newKeys) {
137 | 2 |
           changes.add(new ConfigChange(namespace, newKey, null, current.getProperty(newKey),
138 |  |
               PropertyChangeType.ADDED));
139 | 2 |
         }
140 |  |
141 | 5 |
         for (String removedKey : removedKeys) {
142 | 3 |
           changes.add(new ConfigChange(namespace, removedKey, previous.getProperty(removedKey), null,
143 |  |
               PropertyChangeType.DELETED));
144 | 3 |
         }
145 |  |
146 | 5 |
         for (String commonKey : commonKeys) {
147 | 6 |
           String previousValue = previous.getProperty(commonKey);
148 | 6 |
           String currentValue = current.getProperty(commonKey);
149 | 6 |
           if (Objects.equal(previousValue, currentValue)) {
150 | 0 |
             continue;
151 |  |
           }
152 | 6 |
           changes.add(new ConfigChange(namespace, commonKey, previousValue, currentValue,
153 |  |
               PropertyChangeType.MODIFIED));
154 | 6 |
         }
155 |  |
156 | 5 |
         return changes;
157 |  |
       }
158 |  |
     }