Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
amos-boot-biz
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
项目统一框架
amos-boot-biz
Commits
79d4f044
Commit
79d4f044
authored
Nov 09, 2023
by
KeYong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
提交https远程调用方法
parent
d1442973
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
268 additions
and
13 deletions
+268
-13
HttpContentTypeUtil.java
...yeejoin/equipmanage/common/utils/HttpContentTypeUtil.java
+30
-3
HttpsGetAndPostUtil.java
...yeejoin/equipmanage/common/utils/HttpsGetAndPostUtil.java
+201
-0
ISyncDataService.java
...ava/com/yeejoin/equipmanage/service/ISyncDataService.java
+2
-2
MqttReceiveServiceImpl.java
...join/equipmanage/service/impl/MqttReceiveServiceImpl.java
+17
-4
SyncDataServiceImpl.java
...yeejoin/equipmanage/service/impl/SyncDataServiceImpl.java
+8
-3
DcsUtil.java
.../src/main/java/com/yeejoin/equipmanage/utils/DcsUtil.java
+8
-1
application-dev.properties
...ystem-equip/src/main/resources/application-dev.properties
+2
-0
No files found.
amos-boot-module/amos-boot-module-api/amos-boot-module-equip-api/src/main/java/com/yeejoin/equipmanage/common/utils/HttpContentTypeUtil.java
View file @
79d4f044
...
...
@@ -10,6 +10,7 @@ import org.apache.http.config.Registry;
import
org.apache.http.config.RegistryBuilder
;
import
org.apache.http.conn.socket.ConnectionSocketFactory
;
import
org.apache.http.conn.socket.PlainConnectionSocketFactory
;
import
org.apache.http.conn.ssl.NoopHostnameVerifier
;
import
org.apache.http.conn.ssl.SSLConnectionSocketFactory
;
import
org.apache.http.conn.ssl.TrustSelfSignedStrategy
;
import
org.apache.http.entity.ContentType
;
...
...
@@ -21,10 +22,12 @@ import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import
org.apache.http.impl.client.HttpClients
;
import
org.apache.http.impl.conn.PoolingHttpClientConnectionManager
;
import
org.apache.http.ssl.SSLContextBuilder
;
import
org.apache.http.ssl.SSLContexts
;
import
org.apache.http.util.EntityUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.net.ssl.SSLContext
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStreamReader
;
...
...
@@ -63,11 +66,12 @@ public class HttpContentTypeUtil {
//System.out.println("初始化HttpClientTest~~~开始");
SSLContextBuilder
builder
=
new
SSLContextBuilder
();
builder
.
loadTrustMaterial
(
null
,
new
TrustSelfSignedStrategy
());
SSLConnectionSocketFactory
sslsf
=
new
SSLConnectionSocketFactory
(
builder
.
build
());
// SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
// builder.build(), NoopHostnameVerifier.INSTANCE);
SSLContext
ctx
=
SSLContexts
.
createSystemDefault
();
SSLConnectionSocketFactory
sslsf
=
new
SSLConnectionSocketFactory
(
builder
.
build
(),
new
String
[]{
"TLSv1"
,
"TLSv1.2"
},
null
,
NoopHostnameVerifier
.
INSTANCE
);
// 配置同时支持 HTTP 和 HTPPS
Registry
<
ConnectionSocketFactory
>
socketFactoryRegistry
=
RegistryBuilder
.<
ConnectionSocketFactory
>
create
().
register
(
"http"
,
PlainConnectionSocketFactory
.
getSocketFactory
()).
register
(
"https"
,
sslsf
).
build
();
// 初始化连接管理器
pool
=
new
PoolingHttpClientConnectionManager
(
...
...
@@ -110,6 +114,7 @@ public class HttpContentTypeUtil {
* 发送Post请求
*/
private
static
String
sendHttpPost
(
HttpPost
httpPost
)
{
log
.
info
(
"================httpPost信息: "
+
JSON
.
toJSONString
(
httpPost
));
CloseableHttpClient
httpClient
=
null
;
CloseableHttpResponse
response
=
null
;
// 响应内容
...
...
@@ -602,4 +607,25 @@ public class HttpContentTypeUtil {
}
return
sendHttpPost
(
httpPost
);
}
public
static
String
sendHttpPostFormWithHeader
(
String
httpUrl
,
Map
<
String
,
String
>
params
,
Map
<
String
,
String
>
headerMap
)
{
HttpPost
httpPost
=
new
HttpPost
(
httpUrl
);
// 创建httpPost
try
{
for
(
Map
.
Entry
<
String
,
String
>
entry
:
headerMap
.
entrySet
())
{
httpPost
.
setHeader
(
entry
.
getKey
(),
entry
.
getValue
());
}
// 设置参数
MultipartEntityBuilder
builder
=
MultipartEntityBuilder
.
create
();
if
(
params
!=
null
)
{
for
(
String
key:
params
.
keySet
())
{
builder
.
addPart
(
key
,
new
StringBody
(
params
.
get
(
key
),
ContentType
.
create
(
"text/plain"
,
Consts
.
UTF_8
)));
}
HttpEntity
entity
=
builder
.
build
();
httpPost
.
setEntity
(
entity
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
sendHttpPost
(
httpPost
);
}
}
\ No newline at end of file
amos-boot-module/amos-boot-module-api/amos-boot-module-equip-api/src/main/java/com/yeejoin/equipmanage/common/utils/HttpsGetAndPostUtil.java
0 → 100644
View file @
79d4f044
package
com
.
yeejoin
.
equipmanage
.
common
.
utils
;
import
com.alibaba.fastjson.JSON
;
import
org.apache.http.NameValuePair
;
import
org.apache.http.client.CookieStore
;
import
org.apache.http.client.entity.UrlEncodedFormEntity
;
import
org.apache.http.client.methods.CloseableHttpResponse
;
import
org.apache.http.client.methods.HttpGet
;
import
org.apache.http.client.methods.HttpPost
;
import
org.apache.http.client.utils.URIBuilder
;
import
org.apache.http.conn.ssl.NoopHostnameVerifier
;
import
org.apache.http.conn.ssl.SSLConnectionSocketFactory
;
import
org.apache.http.entity.ContentType
;
import
org.apache.http.entity.StringEntity
;
import
org.apache.http.impl.client.BasicCookieStore
;
import
org.apache.http.impl.client.CloseableHttpClient
;
import
org.apache.http.impl.client.HttpClients
;
import
org.apache.http.message.BasicNameValuePair
;
import
org.apache.http.util.EntityUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.net.ssl.SSLContext
;
import
javax.net.ssl.TrustManager
;
import
javax.net.ssl.X509TrustManager
;
import
java.io.IOException
;
import
java.net.URI
;
import
java.security.KeyManagementException
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.cert.CertificateException
;
import
java.security.cert.X509Certificate
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author keyong
* @title: HttpsGetAndPostUtil
* <pre>
* @description: TODO
* </pre>
* @date 2023/11/9 8:30
*/
public
class
HttpsGetAndPostUtil
{
private
final
Logger
logger
=
LoggerFactory
.
getLogger
(
HttpsGetAndPostUtil
.
class
);
private
static
CookieStore
cookieStore
=
new
BasicCookieStore
();
public
static
String
doGet
(
String
url
,
Map
<
String
,
String
>
param
)
{
// 创建Httpclient对象
CloseableHttpClient
httpclient
=
wrapClient
();
String
resultString
=
""
;
CloseableHttpResponse
response
=
null
;
try
{
// 创建uri
URIBuilder
builder
=
new
URIBuilder
(
url
);
if
(
param
!=
null
)
{
for
(
String
key
:
param
.
keySet
())
{
builder
.
addParameter
(
key
,
param
.
get
(
key
));
}
}
URI
uri
=
builder
.
build
();
// 创建http GET请求
HttpGet
httpGet
=
new
HttpGet
(
uri
);
// 执行请求
response
=
httpclient
.
execute
(
httpGet
);
// 判断返回状态是否为200
if
(
response
.
getStatusLine
().
getStatusCode
()
==
200
)
{
resultString
=
EntityUtils
.
toString
(
response
.
getEntity
(),
"UTF-8"
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
try
{
if
(
response
!=
null
)
{
response
.
close
();
}
httpclient
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
return
resultString
;
}
public
static
String
doGet
(
String
url
)
{
return
doGet
(
url
,
null
);
}
public
static
String
doPost
(
String
url
,
Map
<
String
,
String
>
param
)
throws
NoSuchAlgorithmException
,
KeyManagementException
{
// 创建Httpclient对象
CloseableHttpClient
httpClient
=
wrapClient
();
CloseableHttpResponse
response
=
null
;
String
resultString
=
""
;
try
{
// 创建Http Post请求
HttpPost
httpPost
=
new
HttpPost
(
url
);
// 创建参数列表
if
(
param
!=
null
)
{
List
<
NameValuePair
>
paramList
=
new
ArrayList
<>();
for
(
String
key
:
param
.
keySet
())
{
paramList
.
add
(
new
BasicNameValuePair
(
key
,
param
.
get
(
key
)));
}
// 模拟表单
UrlEncodedFormEntity
entity
=
new
UrlEncodedFormEntity
(
paramList
,
"utf-8"
);
httpPost
.
setEntity
(
entity
);
}
// 执行http请求
response
=
httpClient
.
execute
(
httpPost
);
resultString
=
EntityUtils
.
toString
(
response
.
getEntity
(),
"utf-8"
);
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
e
);
}
finally
{
try
{
response
.
close
();
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
}
System
.
out
.
println
(
"新方法返回++++++++++++++++++++++++++++++"
+
JSON
.
toJSONString
(
resultString
));
return
resultString
;
}
public
static
String
doPost
(
String
url
)
throws
NoSuchAlgorithmException
,
KeyManagementException
{
return
doPost
(
url
,
null
);
}
public
static
String
doPostJson
(
String
url
,
String
json
)
{
// 创建Httpclient对象
CloseableHttpClient
httpClient
=
wrapClient
();
CloseableHttpResponse
response
=
null
;
String
resultString
=
""
;
try
{
// 创建Http Post请求
HttpPost
httpPost
=
new
HttpPost
(
url
);
// 创建请求内容
StringEntity
entity
=
new
StringEntity
(
json
,
ContentType
.
APPLICATION_JSON
);
httpPost
.
setEntity
(
entity
);
// 执行http请求
response
=
httpClient
.
execute
(
httpPost
);
resultString
=
EntityUtils
.
toString
(
response
.
getEntity
(),
"utf-8"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
try
{
response
.
close
();
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
}
return
resultString
;
}
/**
* @return HttpClient
* @Description 创建一个不进行正式验证的请求客户端对象 不用导入SSL证书
*/
public
static
CloseableHttpClient
wrapClient
()
{
try
{
SSLContext
ctx
=
SSLContext
.
getInstance
(
"TLS"
);
ctx
.
init
(
null
,
trustManager
(),
null
);
SSLConnectionSocketFactory
ssf
=
new
SSLConnectionSocketFactory
(
ctx
,
NoopHostnameVerifier
.
INSTANCE
);
return
HttpClients
.
custom
()
.
setSSLSocketFactory
(
ssf
)
//cookie获取
.
setDefaultCookieStore
(
cookieStore
)
.
build
();
}
catch
(
Exception
e
)
{
return
HttpClients
.
createDefault
();
}
}
private
static
TrustManager
[]
trustManager
()
{
return
new
TrustManager
[]{
new
X509TrustManager
()
{
@Override
public
X509Certificate
[]
getAcceptedIssuers
()
{
return
null
;
}
@Override
public
void
checkClientTrusted
(
X509Certificate
[]
arg0
,
String
arg1
)
throws
CertificateException
{
}
@Override
public
void
checkServerTrusted
(
X509Certificate
[]
arg0
,
String
arg1
)
throws
CertificateException
{
}
}};
}
}
amos-boot-module/amos-boot-module-biz/amos-boot-module-equip-biz/src/main/java/com/yeejoin/equipmanage/service/ISyncDataService.java
View file @
79d4f044
...
...
@@ -83,9 +83,9 @@ public interface ISyncDataService {
void
syncUpdatedFireFightingSystem
(
Collection
<
FireFightingSystem
>
list
);
void
syncCreatedSendAlarm
(
Collection
<
EquipmentSpecificAlarmLog
>
list
);
void
syncCreatedSendAlarm
(
Collection
<
EquipmentSpecificAlarmLog
>
list
)
throws
InterruptedException
;
void
syncCreatedSendAlarmReport
(
EquipmentSpecificAlarmLog
ent
);
void
syncCreatedSendAlarmReport
(
EquipmentSpecificAlarmLog
ent
)
throws
InterruptedException
;
void
syncCreatedBuilding
(
List
<
FormInstance
>
list
);
...
...
amos-boot-module/amos-boot-module-biz/amos-boot-module-equip-biz/src/main/java/com/yeejoin/equipmanage/service/impl/MqttReceiveServiceImpl.java
View file @
79d4f044
...
...
@@ -626,7 +626,11 @@ public class MqttReceiveServiceImpl implements MqttReceiveService {
publishDataToCanvas
(
equipmentSpecificIndexList
);
// 向其他系统推送报警
equipmentAlarmLogsToOtherSystems
(
alarmLogs
);
try
{
equipmentAlarmLogsToOtherSystems
(
alarmLogs
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
if
(
equipmentSpecificVo
.
getEcode
()
!=
null
)
{
String
ecode
=
equipmentSpecificVo
.
getEcode
();
...
...
@@ -876,7 +880,11 @@ public class MqttReceiveServiceImpl implements MqttReceiveService {
publishDataToCanvas
(
equipmentSpecificIndexList
);
// 向其他系统推送报警
equipmentAlarmLogsToOtherSystems
(
alarmLogs
);
try
{
equipmentAlarmLogsToOtherSystems
(
alarmLogs
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
if
(
equipmentSpecificVo
.
getEcode
()
!=
null
)
{
String
ecode
=
equipmentSpecificVo
.
getEcode
();
...
...
@@ -1161,7 +1169,11 @@ public class MqttReceiveServiceImpl implements MqttReceiveService {
publishDataToCanvas
(
equipmentSpecificIndexList
);
// 向其他系统推送报警
equipmentAlarmLogsToOtherSystems
(
alarmLogs
);
try
{
equipmentAlarmLogsToOtherSystems
(
alarmLogs
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
if
(
vo
.
getEcode
()
!=
null
)
{
String
ecode
=
vo
.
getEcode
();
...
...
@@ -1771,7 +1783,7 @@ public class MqttReceiveServiceImpl implements MqttReceiveService {
*
* @param equipmentAlarmLogs
*/
public
void
equipmentAlarmLogsToOtherSystems
(
List
<
EquipmentSpecificAlarmLog
>
equipmentAlarmLogs
)
{
public
void
equipmentAlarmLogsToOtherSystems
(
List
<
EquipmentSpecificAlarmLog
>
equipmentAlarmLogs
)
throws
InterruptedException
{
if
(
ObjectUtils
.
isEmpty
(
equipmentAlarmLogs
))
{
return
;
}
...
...
@@ -1811,6 +1823,7 @@ public class MqttReceiveServiceImpl implements MqttReceiveService {
}
// 向南瑞平台推送报警消息
log
.
info
(
"判断条件bool值为:"
+
JSON
.
toJSONString
(
bool
)
+
", NRMsgSend值为:"
+
JSON
.
toJSONString
(
NRMsgSend
));
if
(!
bool
&&
NRMsgSend
)
{
syncDataService
.
syncCreatedSendAlarm
(
equipmentAlarmLogs
);
}
...
...
amos-boot-module/amos-boot-module-biz/amos-boot-module-equip-biz/src/main/java/com/yeejoin/equipmanage/service/impl/SyncDataServiceImpl.java
View file @
79d4f044
...
...
@@ -25,6 +25,7 @@ import com.yeejoin.equipmanage.utils.DcsUtil;
import
com.yeejoin.equipmanage.utils.SyncDataUtil
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.http.nio.client.HttpAsyncClient
;
import
org.eclipse.paho.client.mqttv3.MqttException
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -397,7 +398,7 @@ public class SyncDataServiceImpl implements ISyncDataService {
}
@Override
public
void
syncCreatedSendAlarm
(
Collection
<
EquipmentSpecificAlarmLog
>
list
)
{
public
void
syncCreatedSendAlarm
(
Collection
<
EquipmentSpecificAlarmLog
>
list
)
throws
InterruptedException
{
equipAlarmDataSync
((
List
<
EquipmentSpecificAlarmLog
>)
list
);
}
...
...
@@ -420,7 +421,7 @@ public class SyncDataServiceImpl implements ISyncDataService {
}
@Override
public
void
syncCreatedSendAlarmReport
(
EquipmentSpecificAlarmLog
ent
)
{
public
void
syncCreatedSendAlarmReport
(
EquipmentSpecificAlarmLog
ent
)
throws
InterruptedException
{
equipAlarmDataSync
(
Arrays
.
asList
(
ent
));
}
...
...
@@ -442,8 +443,9 @@ public class SyncDataServiceImpl implements ISyncDataService {
//redisTemplate.opsForValue().set(message.redisKey(), new String(message.message2Bytes()));
}
void
equipAlarmDataSync
(
List
<
EquipmentSpecificAlarmLog
>
list
)
{
void
equipAlarmDataSync
(
List
<
EquipmentSpecificAlarmLog
>
list
)
throws
InterruptedException
{
if
(
CollectionUtils
.
isNotEmpty
(
list
))
{
Thread
.
sleep
(
2000
);
List
<
Long
>
idList
=
list
.
stream
().
filter
(
x
->
x
.
getBuildId
()
!=
null
).
map
(
EquipmentSpecificAlarmLog:
:
getId
).
collect
(
Collectors
.
toList
());
List
<
Long
>
idBNullList
=
list
.
stream
().
filter
(
x
->
x
.
getBuildId
()
==
null
).
map
(
EquipmentSpecificAlarmLog:
:
getId
).
collect
(
Collectors
.
toList
());
if
(
CollectionUtils
.
isNotEmpty
(
idList
)
||
CollectionUtils
.
isNotEmpty
(
idBNullList
))
{
...
...
@@ -486,8 +488,11 @@ public class SyncDataServiceImpl implements ISyncDataService {
alarmList
.
add
(
map
);
}
warnMap
.
put
(
"warns"
,
alarmList
);
logger
.
info
(
"开始调用平台服务存储告警数据warns:"
+
JSON
.
toJSONString
(
alarmList
));
requestVo
.
setBody
(
warnMap
);
logger
.
info
(
"==============header:"
+
JSON
.
toJSONString
(
headerMap
)
+
"; body: "
+
JSON
.
toJSONString
(
requestVo
));
String
s
=
HttpContentTypeUtil
.
sendHttpPostJsonWithHeader
(
sendAlarmUrl
,
JSON
.
toJSONString
(
requestVo
),
headerMap
);
logger
.
info
(
"===============告警推送联调==================返回数据:"
+
s
);
}
}
catch
(
Exception
e
)
{
...
...
amos-boot-module/amos-boot-module-biz/amos-boot-module-equip-biz/src/main/java/com/yeejoin/equipmanage/utils/DcsUtil.java
View file @
79d4f044
package
com
.
yeejoin
.
equipmanage
.
utils
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.yeejoin.equipmanage.common.datasync.vo.AppTokenVo
;
import
com.yeejoin.equipmanage.common.utils.HttpContentTypeUtil
;
import
com.yeejoin.equipmanage.common.utils.HttpsGetAndPostUtil
;
import
org.apache.commons.lang3.StringUtils
;
import
org.json.JSONString
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
...
@@ -56,6 +59,7 @@ public class DcsUtil {
private
RedisTemplate
<
String
,
String
>
redisTemplate
;
public
String
getDcsToken
()
throws
Exception
{
logger
.
info
(
"开始获取登录token++++++++++++++"
);
String
accessToken
=
""
;
// accessToken = redisTemplate.opsForValue().get(tokenKey);
if
(!
StringUtils
.
isNotBlank
(
accessToken
))
{
...
...
@@ -67,7 +71,8 @@ public class DcsUtil {
map
.
put
(
"scope"
,
scope
);
map
.
put
(
"client_id"
,
clientId
);
map
.
put
(
"client_secret"
,
clientSecret
);
String
content
=
HttpContentTypeUtil
.
doPostForm
(
gettokenUrl
,
map
);
String
content
=
HttpsGetAndPostUtil
.
doPost
(
gettokenUrl
,
map
);
logger
.
info
(
"header:"
+
JSON
.
toJSONString
(
headerMap
)
+
"; body: "
+
JSON
.
toJSONString
(
map
)
+
"; 调用获取token返回:"
+
content
);
if
(
StringUtils
.
isNotBlank
(
content
))
{
AppTokenVo
appTokenVo
=
JSONObject
.
parseObject
(
content
,
AppTokenVo
.
class
);
// accessToken = String.join(" ", appTokenVo.getToken_type(), appTokenVo.getAccess_token());
...
...
@@ -76,6 +81,7 @@ public class DcsUtil {
redisTemplate
.
opsForValue
().
set
(
tokenKey
,
accessToken
,
expiresIn
);
}
}
logger
.
info
(
"accessToken 是----------"
+
accessToken
);
return
accessToken
;
}
}
\ No newline at end of file
amos-boot-system-equip/src/main/resources/application-dev.properties
View file @
79d4f044
...
...
@@ -80,6 +80,8 @@ dcs.x.hw.id=io.cs
dcs.x.hw.appKey
=
i!YmnHgJ=Ysz8V+O@ZG237inQKfixkQ.-#-P3IlR8fO%.#F!g%35Z#@tp$6G+52v
dcs.url.token
=
http://198.87.103.158:8001/auth-service/oauth/token
dcs.url.sendalarm
=
http://198.87.103.158:8001/alarm-service/appalarm/sendalarm
#dcs.url.token=https://192.168.4.89/v1/cs/auth-service/oauth/token
#dcs.url.sendalarm=https://192.168.4.89/v1/cs/alarm-service/appalarm/sendalarm
#??????
param.system.online.date
=
2019-02-12
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment