Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
Distributed Computing and Network Fusion System
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
3
Issues
3
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
WirelessInformationCollaborate
Distributed Computing and Network Fusion System
Commits
76dad701
Commit
76dad701
authored
Aug 12, 2020
by
ymwang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
动态网络拓扑下发
parent
a86f0292
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
182 additions
and
80 deletions
+182
-80
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/dynamicNet/CycleTopoUnit.java
.../java/top/ninwoo/weixingsim/dynamicNet/CycleTopoUnit.java
+45
-57
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/dynamicNet/DoMap.java
...src/main/java/top/ninwoo/weixingsim/dynamicNet/DoMap.java
+3
-3
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/dynamicNet/TimeExpanGraph.java
...java/top/ninwoo/weixingsim/dynamicNet/TimeExpanGraph.java
+13
-13
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/sateTopology/WxMain.java
.../main/java/top/ninwoo/weixingsim/sateTopology/WxMain.java
+17
-0
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/sateTopology/init/Initapp.java
...java/top/ninwoo/weixingsim/sateTopology/init/Initapp.java
+5
-3
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/sateTopology/service/Weixing.java
...a/top/ninwoo/weixingsim/sateTopology/service/Weixing.java
+1
-0
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/test/java/top/ninwoo/test/TopoTests.java
...fer-topology/src/test/java/top/ninwoo/test/TopoTests.java
+94
-0
cnf-cloud-center/src/main/resources/application.yml
cnf-cloud-center/src/main/resources/application.yml
+2
-2
cnf-edge-center/src/main/resources/application.yaml
cnf-edge-center/src/main/resources/application.yaml
+2
-2
No files found.
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/dynamicNet/CycleTopoUnit.java
View file @
76dad701
...
...
@@ -9,83 +9,71 @@ import java.io.File;
import
java.util.*
;
public
class
CycleTopoUnit
{
public
static
void
main
(
String
[]
args
)
{
cycleTp
E
();
public
static
void
main
(
String
[]
args
)
throws
IllegalAccessException
{
cycleTp
();
}
public
static
HashMap
<
Integer
,
double
[][]>
cycleTpE
()
{
public
static
HashMap
<
Integer
,
int
[][]>
cycleTp
()
{
//从文本中获取卫星的数据
WeixingImpl
wx
=
new
WeixingImpl
();
ToponetImpl
tp
=
new
ToponetImpl
();
SimData
sd
=
new
SimData
();
//tp.delHistory();
File
file
=
new
File
(
"D:\\project\\topusim_1.txt"
);
//D:\LabratoryJavaPro\codingDownload\latestCoding\
File
file
=
new
File
(
"F:\\ymwang\\topusim_1.txt"
);
List
<
WeiXingData
>
wxData
=
null
;
{
try
{
wxData
=
wx
.
iniTopo
(
file
,
sd
.
getZhouqi
());
}
catch
(
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
try
{
wxData
=
wx
.
iniTopo
(
file
,
sd
.
getZhouqi
());
}
catch
(
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
//初始topo
int
[][]
toponet
=
tp
.
getTopology
(
wxData
,
sd
);
//去掉ovs
double
[][]
topoNet
=
new
double
[
6
][
6
];
//卫星节点数目 卫星组成的网络拓扑
for
(
int
i
=
0
;
i
<
topoNet
.
length
;
i
++){
for
(
int
j
=
0
;
j
<
topoNet
.
length
;
j
++){
topoNet
[
i
][
j
]
=
toponet
[
i
][
j
];
}
}
HashMap
<
Integer
,
double
[][]>
TopoStore
=
new
HashMap
<>();
TopoStore
.
put
(
0
,
topoNet
);
sd
.
setJiange
(
60
);
sd
.
setC0
(
3
e10
);
for
(
int
i
=
1
;
i
<
sd
.
getZhouqi
()/
sd
.
getJiange
();
i
++)
{
//存储全周期拓扑
HashMap
<
Integer
,
int
[][]>
TopoStore
=
new
HashMap
<>();
out:
for
(
int
i
=
0
;
i
<
sd
.
getZhouqi
()/
sd
.
getJiange
();
i
++)
{
//Thread.sleep(2000);
int
time
=
i
*
sd
.
getJiange
();
List
<
WeiXingData
>
changetp
=
wx
.
changeTopo
(
wxData
,
time
);
int
[][]
changeTopo
=
tp
.
getTopology
(
changetp
,
sd
);
//去掉ovs
for
(
int
k
=
0
;
k
<
topoNet
.
length
;
k
++){
for
(
int
j
=
0
;
j
<
topoNet
.
length
;
j
++){
topoNet
[
k
][
j
]
=
changeTopo
[
k
][
j
];
}
}
for
(
int
k
=
0
;
k
<
topoNet
.
length
;
k
++){
for
(
int
j
=
k
+
1
;
j
<
topoNet
.
length
;
j
++){
topoNet
[
k
][
j
]
=
topoNet
[
j
][
k
];
}
}
TopoStore
.
put
(
i
,
topoNet
);
int
[][]
topoChange
=
tp
.
getTopology
(
changetp
,
sd
);
TopoStore
.
put
(
i
,
topoChange
);
}
/*
* 对比全周期拓扑
* count记录重复拓扑行数
* count2记录不同拓扑数目
* */
int
count
=
0
;
int
count2
=
-
1
;
Iterator
<
Map
.
Entry
<
Integer
,
double
[][]>>
iterator
=
TopoStore
.
entrySet
().
iterator
();
while
(
iterator
.
hasNext
()){
double
[][]
value
=
iterator
.
next
().
getValue
();
for
(
int
i
=
0
;
i
<
value
.
length
;
i
++){
if
(
i
>
0
){
boolean
equals
=
Arrays
.
equals
(
value
[
i
],
topoNet
[
i
]);
int
count2
=
0
;
Iterator
<
Map
.
Entry
<
Integer
,
int
[][]>>
iterator
=
TopoStore
.
entrySet
().
iterator
();
while
(
iterator
.
hasNext
()){
int
[][]
value
=
iterator
.
next
().
getValue
();
System
.
out
.
println
(
Arrays
.
deepToString
(
value
));
System
.
out
.
println
(
"========================================="
);
System
.
out
.
println
(
count2
);
while
(
iterator
.
hasNext
()){
int
[][]
valueNext
=
iterator
.
next
().
getValue
();
for
(
int
i
=
0
;
i
<
value
.
length
;
i
++){
boolean
equals
=
Arrays
.
equals
(
value
[
i
],
valueNext
[
i
]);
count
+=
(
equals
?
1
:
0
);
}
for
(
int
j
=
0
;
j
<
topoNet
.
length
;
j
++){
topoNet
[
i
][
j
]
=
value
[
i
][
j
];
}
}
for
(
int
k
=
0
;
k
<
topoNet
.
length
;
k
++){
for
(
int
j
=
k
+
1
;
j
<
topoNet
.
length
;
j
++){
topoNet
[
k
][
j
]
=
topoNet
[
j
][
k
];
}
if
(
count
!=
30
){
System
.
out
.
println
(
Arrays
.
deepToString
(
valueNext
));
System
.
out
.
println
(
"========================================="
);
System
.
out
.
println
(
count2
);
count2
++;
}
count
=
0
;
value
=
valueNext
;
}
if
(
count
!=
30
){
count2
++;
}
System
.
out
.
println
(
Arrays
.
deepToString
(
topoNet
));
System
.
out
.
println
(
"========================================="
);
System
.
out
.
println
(
count2
);
}
return
TopoStore
;
}
}
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/dynamicNet/DoMap.java
View file @
76dad701
...
...
@@ -6,7 +6,7 @@ import java.util.HashMap;
import
java.util.LinkedList
;
import
java.util.Stack
;
import
static
top
.
ninwoo
.
weixingsim
.
dynamicNet
.
CycleTopo
Unit
.
cycleTpE
;
import
static
top
.
ninwoo
.
weixingsim
.
dynamicNet
.
CycleTopo
.
cycleTp
;
/**
...
...
@@ -146,8 +146,8 @@ public class DoMap {
}
int
slotKey
=
(
int
)
((((
System
.
currentTimeMillis
()-
time
)/
20
/
1000
)-
1
)%
300
+
1
);
startT
=
((
System
.
currentTimeMillis
()-
time
)/
20000
+
1
)*
20000
;
//
HashMap<Integer, double[][]> cycleTp = cycleTp();
HashMap
<
Integer
,
double
[][]>
cycleTp
=
cycleTpE
();
HashMap
<
Integer
,
double
[][]>
cycleTp
=
cycleTp
();
//
HashMap<Integer, double[][]> cycleTp = cycleTpE();
//获得单时隙连接矩阵 0或MAXWEIGHT
...
...
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/dynamicNet/TimeExpanGraph.java
View file @
76dad701
...
...
@@ -6,7 +6,7 @@ import java.util.HashMap;
import
java.util.LinkedList
;
import
java.util.Stack
;
import
static
top
.
ninwoo
.
weixingsim
.
dynamicNet
.
CycleTopoUnit
.
cycleTp
E
;
import
static
top
.
ninwoo
.
weixingsim
.
dynamicNet
.
CycleTopoUnit
.
cycleTp
;
public
class
TimeExpanGraph
{
...
...
@@ -38,7 +38,7 @@ public class TimeExpanGraph {
dev
=
num
*
slotnum
;
//10个卫星节点,3个时隙,则共有10*3个卫星节点
//组装最短路矩阵
double
[][]
matrixGraph
=
MatrixGraph
();
int
[][]
matrixGraph
=
MatrixGraph
();
System
.
out
.
println
(
"大矩阵是:"
);
for
(
int
i
=
0
;
i
<
matrixGraph
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
matrixGraph
[
0
].
length
;
j
++)
{
...
...
@@ -52,7 +52,7 @@ public class TimeExpanGraph {
}
}
private
static
double
[][]
MatrixGraph
()
{
private
static
int
[][]
MatrixGraph
()
{
//获取当前3时隙拓扑
/**
...
...
@@ -70,11 +70,11 @@ public class TimeExpanGraph {
int
slotKey
=
(
int
)
((((
System
.
currentTimeMillis
()-
time
)/
20
/
1000
)-
1
)%
300
+
1
);
startT
=
((
System
.
currentTimeMillis
()-
time
)/
20000
+
1
)*
20000
;
HashMap
<
Integer
,
double
[][]>
cycleTp
=
cycleTpE
();
HashMap
<
Integer
,
int
[][]>
cycleTp
=
cycleTp
();
//获得第1个时隙的连接矩阵 0或1
double
[][]
currentTp
=
cycleTp
.
get
((
slotKey
)%
300
+
1
);
double
[][]
slot1
=
new
double
[
num
][
num
];
//10*10的矩阵图
int
[][]
currentTp
=
cycleTp
.
get
((
slotKey
)%
300
+
1
);
int
[][]
slot1
=
new
int
[
num
][
num
];
//10*10的矩阵图
for
(
int
i
=
0
;
i
<
slot1
.
length
;
i
++){
for
(
int
j
=
0
;
j
<
slot1
[
0
].
length
;
j
++){
slot1
[
i
][
j
]
=
currentTp
[
i
][
j
];
...
...
@@ -96,12 +96,12 @@ public class TimeExpanGraph {
//获得第2个时隙的连接矩阵
currentTp
=
cycleTp
.
get
((
slotKey
)%
300
+
2
);
double
[][]
slot2
=
new
double
[
num
][
num
];
int
[][]
slot2
=
new
int
[
num
][
num
];
for
(
int
i
=
0
;
i
<
slot2
.
length
;
i
++){
for
(
int
j
=
0
;
j
<
slot2
.
length
;
j
++){
if
(
currentTp
[
i
][
j
]==
0
){
if
(
i
==
j
){
slot2
[
i
][
j
]=
0
.0
;
slot2
[
i
][
j
]=
0
;
}
else
slot2
[
i
][
j
]
=
0
;
}
else
{
...
...
@@ -112,12 +112,12 @@ public class TimeExpanGraph {
//获得第3个时隙的连接矩阵
currentTp
=
cycleTp
.
get
((
slotKey
)%
300
+
3
);
double
[][]
slot3
=
new
double
[
num
][
num
];
int
[][]
slot3
=
new
int
[
num
][
num
];
for
(
int
i
=
0
;
i
<
slot3
.
length
;
i
++){
for
(
int
j
=
0
;
j
<
slot3
.
length
;
j
++){
if
(
currentTp
[
i
][
j
]==
0
){
if
(
i
==
j
){
slot3
[
i
][
j
]=
0
.0
;
slot3
[
i
][
j
]=
0
;
}
else
slot3
[
i
][
j
]
=
0
;
}
else
{
...
...
@@ -126,7 +126,7 @@ public class TimeExpanGraph {
}
}
//生成相邻时隙矩阵
double
[][]
neighbor
=
new
double
[
num
][
num
];
int
[][]
neighbor
=
new
int
[
num
][
num
];
for
(
int
i
=
0
;
i
<
neighbor
.
length
;
i
++){
for
(
int
j
=
0
;
j
<
neighbor
.
length
;
j
++){
if
(
i
==
j
){
...
...
@@ -137,14 +137,14 @@ public class TimeExpanGraph {
}
}
//生成其余时隙矩阵
double
[][]
nonNeighbor
=
new
double
[
num
][
num
];
int
[][]
nonNeighbor
=
new
int
[
num
][
num
];
for
(
int
i
=
0
;
i
<
nonNeighbor
.
length
;
i
++){
for
(
int
j
=
0
;
j
<
nonNeighbor
.
length
;
j
++){
nonNeighbor
[
i
][
j
]
=
0
;
}
}
//组装连接矩阵
double
[][]
edgeWeight
=
new
double
[
dev
][
dev
];
int
[][]
edgeWeight
=
new
int
[
dev
][
dev
];
for
(
int
i
=
0
;
i
<
edgeWeight
.
length
;
i
++){
for
(
int
j
=
0
;
j
<
edgeWeight
[
0
].
length
;
j
++){
if
(
i
>=
0
&
i
<
num
&
j
>=
0
&
j
<
num
)
{
...
...
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/sateTopology/WxMain.java
0 → 100644
View file @
76dad701
package
top.ninwoo.weixingsim.sateTopology
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
@SpringBootApplication
public
class
WxMain
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
WxMain
.
class
,
args
);
/*try {
new Initapp().run();
} catch (Exception e) {
e.printStackTrace();
}*/
}
}
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/sateTopology/init/Initapp.java
View file @
76dad701
...
...
@@ -2,6 +2,7 @@ package top.ninwoo.weixingsim.sateTopology.init;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.CommandLineRunner
;
import
org.springframework.stereotype.Component
;
import
top.ninwoo.bishe.starter.service.ClusterService
;
import
top.ninwoo.common.entity.*
;
import
top.ninwoo.weixingsim.sateTopology.entity.SimData
;
...
...
@@ -26,9 +27,9 @@ public class Initapp implements CommandLineRunner {
SeparatedClusterConfig
separatedClusterConfig
=
new
SeparatedClusterConfig
();
List
<
ContainerDescription
>
cds
=
new
ArrayList
<>();
// TODO: 这个ID应该是从借口获取的
separatedClusterConfig
.
setEdgeNodeId
(
"192.168.
190.135
:18088"
);
separatedClusterConfig
.
setEdgeNodeId
(
"192.168.
31.198
:18088"
);
ClusterConfig
clusterConfig
=
new
ClusterConfig
();
clusterConfig
.
setId
(
11111
l
);
clusterConfig
.
setId
(
11111
L
);
clusterConfig
.
setOwner
(
"joliu"
);
//从文本中获取卫星的数据
...
...
@@ -36,7 +37,8 @@ public class Initapp implements CommandLineRunner {
ToponetImpl
tp
=
new
ToponetImpl
();
SimData
sd
=
new
SimData
();
//tp.delHistory();
File
file
=
new
File
(
"C:\\WorkSpace\\test\\topusim_1.txt"
);
File
file
=
new
File
(
"D:\\LabratoryJavaPro\\codingDownload\\latestCoding\\topusim_1.txt"
);
List
<
WeiXingData
>
wxData
=
wx
.
iniTopo
(
file
,
sd
.
getZhouqi
());
int
[][]
toponet
=
tp
.
getTopology
(
wxData
,
sd
);
...
...
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/main/java/top/ninwoo/weixingsim/sateTopology/service/Weixing.java
View file @
76dad701
package
top.ninwoo.weixingsim.sateTopology.service
;
import
top.ninwoo.weixingsim.sateTopology.entity.SimData
;
import
top.ninwoo.weixingsim.sateTopology.entity.WeiXingData
;
import
java.io.File
;
...
...
apps/cnf-distributed-file-transfer/dfs-transfer-topology/src/test/java/top/ninwoo/test/TopoTests.java
0 → 100644
View file @
76dad701
package
top.ninwoo.test
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.test.context.junit4.SpringRunner
;
import
top.ninwoo.bishe.starter.service.ClusterService
;
import
top.ninwoo.bishe.starter.service.NetworkService
;
import
top.ninwoo.common.entity.*
;
import
top.ninwoo.weixingsim.WxMain
;
import
top.ninwoo.weixingsim.sateTopology.entity.SimData
;
import
top.ninwoo.weixingsim.sateTopology.entity.WeiXingData
;
import
top.ninwoo.weixingsim.sateTopology.service.impl.ToponetImpl
;
import
top.ninwoo.weixingsim.sateTopology.service.impl.WeixingImpl
;
import
javax.annotation.Resource
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
@RunWith
(
SpringRunner
.
class
)
@SpringBootTest
(
classes
=
WxMain
.
class
)
public
class
TopoTests
{
@Autowired
private
ClusterService
clusterService
;
@Resource
private
NetworkService
networkService
;
@Test
public
void
test3
()
throws
IllegalAccessException
,
InterruptedException
{
ArrayList
<
SeparatedClusterConfig
>
clusterConfigs
=
new
ArrayList
<>();
SeparatedClusterConfig
separatedClusterConfig
=
new
SeparatedClusterConfig
();
List
<
ContainerDescription
>
cds
=
new
ArrayList
<>();
// TODO: 这个ID应该是从借口获取的
separatedClusterConfig
.
setEdgeNodeId
(
"192.168.31.198:18088"
);
ClusterConfig
clusterConfig
=
new
ClusterConfig
();
clusterConfig
.
setId
(
11111
l
);
clusterConfig
.
setOwner
(
"joliu"
);
//从文本中获取卫星的数据
WeixingImpl
wx
=
new
WeixingImpl
();
ToponetImpl
tp
=
new
ToponetImpl
();
SimData
sd
=
new
SimData
();
//tp.delHistory();
File
file
=
new
File
(
"D:\\LabratoryJavaPro\\codingDownload\\latestCoding\\topusim_1.txt"
);
// D:\LabratoryJavaPro\codingDownload\latestCoding\
List
<
WeiXingData
>
wxData
=
wx
.
iniTopo
(
file
,
sd
.
getZhouqi
());
int
[][]
toponet
=
tp
.
getTopology
(
wxData
,
sd
);
//创建容器
ContainerDescription
containerDescription0
=
new
ContainerDescription
();
containerDescription0
.
setMode
(
"normal"
);
containerDescription0
.
setReplicas
(
1
);
DockerContainer
container0
=
new
DockerContainer
();
container0
.
setName
(
wxData
.
get
(
0
).
getName
());
container0
.
setCommand
(
"sh"
);
container0
.
setImage
(
"joliu/networktest:schedule"
);
containerDescription0
.
setDockerContainer
(
container0
);
cds
.
add
(
containerDescription0
);
for
(
int
k
=
1
;
k
<
wxData
.
size
();
k
++)
{
ContainerDescription
containerDescription
=
new
ContainerDescription
();
containerDescription
.
setMode
(
"normal"
);
containerDescription
.
setReplicas
(
1
);
DockerContainer
container
=
new
DockerContainer
();
container
.
setName
(
wxData
.
get
(
k
).
getName
());
container
.
setCommand
(
"sh"
);
container
.
setImage
(
"joliu/networktest:server"
);
containerDescription
.
setDockerContainer
(
container
);
cds
.
add
(
containerDescription
);
}
clusterConfig
.
setDockers
(
cds
);
NetworkTopology
topo
=
new
NetworkTopology
();
topo
.
setAppNames
(
tp
.
getAppNames
(
wxData
));
// 这个参数好像没啥用
topo
.
setTopologyId
(
11
);
topo
.
setTopology
(
toponet
);
clusterConfig
.
setTopology
(
topo
);
separatedClusterConfig
.
setClusterConfig
(
clusterConfig
);
clusterConfigs
.
add
(
separatedClusterConfig
);
clusterService
.
sendClusterConfigToEdgeNode
(
clusterConfigs
);
}
}
cnf-cloud-center/src/main/resources/application.yml
View file @
76dad701
...
...
@@ -3,7 +3,7 @@ server:
zookeeper
:
#url: zk.cnf.org:2181
url
:
192.168.
81.1
:2181
url
:
192.168.
31.190
:2181
bs
:
...
...
@@ -11,4 +11,4 @@ bs:
name
:
my-bs-cloud-center
ipservice
:
#url: ipservice.cnf.org:23333
url
:
192.168.81.1:23333
\ No newline at end of file
url
:
192.168.31.190:23333
\ No newline at end of file
cnf-edge-center/src/main/resources/application.yaml
View file @
76dad701
...
...
@@ -28,13 +28,13 @@ bs:
ip-prefix
:
192
ipservice
:
#ip: ipservice.cnf.org:23333
ip
:
192.168.
81.1
:23333
ip
:
192.168.
31.190
:23333
sdn-controller
:
host
:
sdn.cnf.org
port
:
6653
zookeeper
:
#url: zk.cnf.org:2181
url
:
192.168.
81.1
:2181
url
:
192.168.
31.190
:2181
cnf
:
passwd
:
Vudo3423
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