Passed
Push — v6 ( 95b370...25ce72 )
by 光春
03:13
created

ClusterTopClient::getEnvByApiName()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 12
c 1
b 0
f 0
nc 5
nop 2
dl 0
loc 17
rs 9.2222
1
<?php
2
class ClusterTopClient extends TopClient {
3
4
	private static $dnsconfig;
5
	private static $syncDate = 0;
6
	private static $applicationVar ;
7
	private static $cfgDuration = 10;
8
9
	public function __construct($appkey = "",$secretKey = ""){
10
		ClusterTopClient::$applicationVar = new ApplicationVar;
11
		$this->appkey = $appkey;
12
		$this->secretKey = $secretKey ;
13
		$saveConfig = ClusterTopClient::$applicationVar->getValue();
14
15
		if($saveConfig){
16
			$tmpConfig = $saveConfig['dnsconfig'];
17
			ClusterTopClient::$dnsconfig = $this->object_to_array($tmpConfig);
18
			unset($tmpConfig);
19
20
			ClusterTopClient::$syncDate = $saveConfig['syncDate'];
21
			if(!ClusterTopClient::$syncDate)
22
				ClusterTopClient::$syncDate = 0;
23
		}
24
	}
25
26
	public function __destruct(){
27
		if(ClusterTopClient::$dnsconfig && ClusterTopClient::$syncDate){
28
			ClusterTopClient::$applicationVar->setValue("dnsconfig",ClusterTopClient::$dnsconfig);
29
			ClusterTopClient::$applicationVar->setValue("syncDate",ClusterTopClient::$syncDate);
30
			ClusterTopClient::$applicationVar->write();
31
		}
32
	}
33
34
	public function execute($request = null, $session = null,$bestUrl = null){
35
		$currentDate = date('U');
36
		$syncDuration = $this->getDnsConfigSyncDuration();
37
		$bestUrl = $this->getBestVipUrl($this->gatewayUrl,$request->getApiMethodName(),$session);
38
		if($currentDate - ClusterTopClient::$syncDate > $syncDuration * 60){
39
			$httpdns = new HttpdnsGetRequest;
40
			ClusterTopClient::$dnsconfig = json_decode(parent::execute($httpdns,null,$bestUrl)->result,true);
0 ignored issues
show
Bug introduced by
The property result does not seem to exist on ResultSet.
Loading history...
41
			$syncDate = date('U');
42
			ClusterTopClient::$syncDate = $syncDate ;
43
		}
44
		return parent::execute($request,$session,$bestUrl);
45
	}
46
47
	private function getDnsConfigSyncDuration(){
48
		if(ClusterTopClient::$cfgDuration){
49
			return ClusterTopClient::$cfgDuration;
50
		}
51
		if(!ClusterTopClient::$dnsconfig){
52
			return ClusterTopClient::$cfgDuration;
53
		}
54
		$config = json_encode(ClusterTopClient::$dnsconfig);
55
		if(!$config){
56
			return ClusterTopClient::$cfgDuration;
57
		}
58
		$config = ClusterTopClient::$dnsconfig['config'];
59
		$duration = $config['interval'];
60
		ClusterTopClient::$cfgDuration = $duration;
61
62
		return ClusterTopClient::$cfgDuration;
63
	}
64
65
	private function getBestVipUrl($url,$apiname = null,$session = null){
66
		$config = ClusterTopClient::$dnsconfig['config'];
67
		$degrade = $config['degrade'];
68
		if(strcmp($degrade,'true') == 0){
69
			return $url;
70
		}		
71
		$currentEnv = $this->getEnvByApiName($apiname,$session);
72
		$vip = $this->getVipByEnv($url,$currentEnv);
73
		if($vip)
74
			return $vip;
75
		return $url;
76
	}
77
78
	private function getVipByEnv($comUrl,$currentEnv){
79
		$urlSchema = parse_url($comUrl);
80
		if(!$urlSchema)
0 ignored issues
show
Bug Best Practice introduced by
The expression $urlSchema of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
81
			return null;
82
		if(!ClusterTopClient::$dnsconfig['env'])
83
			return null;
84
		
85
		if(!array_key_exists($currentEnv,ClusterTopClient::$dnsconfig['env']))
86
			return null;
87
88
		$hostList = ClusterTopClient::$dnsconfig['env'][$currentEnv];
89
		if(!$hostList)
90
			return null ;
91
92
		$vipList = null;
93
		foreach ($hostList as $key => $value) {
94
			if(strcmp($key,$urlSchema['host']) == 0 && strcmp($value['proto'],$urlSchema['scheme']) == 0){
95
				$vipList = $value;
96
				break;
97
			}
98
		}
99
		$vip = $this->getRandomWeightElement($vipList['vip']);
100
		
101
		if($vip){
102
			return $urlSchema['scheme']."://".$vip.$urlSchema['path'];
103
		}
104
		return null;
105
	}
106
107
	private function getEnvByApiName($apiName,$session=""){
108
		$apiCfgArray = ClusterTopClient::$dnsconfig['api'];
109
		if($apiCfgArray){	
110
			if(array_key_exists($apiName,$apiCfgArray)){
111
				$apiCfg = $apiCfgArray[$apiName];
112
				if(array_key_exists('user',$apiCfg)){
113
					$userFlag = $apiCfg['user'];
114
					$flag = $this->getUserFlag($session);
115
					if($userFlag && $flag ){
116
						return $this->getEnvBySessionFlag($userFlag,$flag);
117
					}else{
118
						return $this->getRandomWeightElement($apiCfg['rule']);
119
					}
120
				}
121
			}
122
		}
123
		return $this->getDeafultEnv();
124
	}
125
126
	private function getUserFlag($session){
127
		if($session && strlen($session) > 5){
128
			if($session[0] == '6' || $session[0] == '7'){
129
				return $session[strlen($session) -1];
130
			}else if($session[0] == '5' || $session[0] == '8'){
131
				return $session[5];
132
			}
133
		}
134
		return null;
135
	}
136
137
	private function getEnvBySessionFlag($targetConfig,$flag){
138
		if($flag){
139
			$userConf = ClusterTopClient::$dnsconfig['user'];
140
			$cfgArry = $userConf[$targetConfig];
141
			foreach ($cfgArry as $key => $value) {
142
				if(in_array($flag,$value))
143
					return $key;
144
			}
145
		}else{
146
			return null;
147
		}
148
	}
149
150
	private function getRandomWeightElement($elements){
151
		$totalWeight = 0;
152
		if($elements){
153
			foreach ($elements as $ele) {
154
				$weight = $this->getElementWeight($ele);
155
				$r = $this->randomFloat() * ($weight + $totalWeight);
156
				if($r >= $totalWeight){
157
					$selected = $ele;
158
				}
159
				$totalWeight += $weight;
160
			}
161
			if($selected){
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $selected does not seem to be defined for all execution paths leading up to this point.
Loading history...
162
				return $this->getElementValue($selected);
163
			}
164
		}
165
		return null;
166
167
	}
168
169
	private function getElementWeight($ele){
170
		$params = explode('|', $ele);
171
		return floatval($params[1]);
172
	}
173
	private function getElementValue($ele){
174
		$params = explode('|', $ele);
175
		return $params[0];		
176
	}
177
178
	private function getDeafultEnv(){
179
		return ClusterTopClient::$dnsconfig['config']['def_env'];
180
	}
181
182
	private static function startsWith($haystack, $needle) {
0 ignored issues
show
Unused Code introduced by
The method startsWith() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
183
    	return $needle === "" || strpos($haystack, $needle) === 0;
184
	}
185
186
	private function object_to_array($obj) 
187
	{ 
188
    	$_arr= is_object($obj) ? get_object_vars($obj) : $obj; 
189
    	foreach($_arr as $key=> $val) 
190
    	{ 
191
        	$val= (is_array($val) || is_object($val))? $this->object_to_array($val) : $val; 
192
        	$arr[$key] = $val; 
193
    	} 
194
    	return$arr; 
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $arr seems to be defined by a foreach iteration on line 189. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
195
	}
196
197
	private function randomFloat($min = 0, $max = 1) { return $min + mt_rand() / mt_getrandmax() * ($max - $min); }
198
}
199
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...