Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-WIC-Cnf
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
CommunityXG
OpenXG-WIC-Cnf
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