Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
data-computing-proxy-test
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
李振振
data-computing-proxy-test
Commits
3acd910f
Commit
3acd910f
authored
Dec 15, 2023
by
李振振
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
11
parent
fe7d9fcc
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
226 additions
and
244 deletions
+226
-244
pom.xml
pom.xml
+8
-13
src/main/java/com/beagle/informix/BaseApplication.java
src/main/java/com/beagle/informix/BaseApplication.java
+2
-0
src/main/java/com/beagle/informix/entity/mybatis/Vccinfo.java
...main/java/com/beagle/informix/entity/mybatis/Vccinfo.java
+41
-41
src/main/java/com/beagle/informix/mapper/VccinfoMapper.java
src/main/java/com/beagle/informix/mapper/VccinfoMapper.java
+25
-22
src/main/java/com/beagle/informix/service/InformixService.java
...ain/java/com/beagle/informix/service/InformixService.java
+4
-1
src/main/java/com/beagle/informix/service/impl/InformixJdbcProxyServiceImpl.java
...e/informix/service/impl/InformixJdbcProxyServiceImpl.java
+30
-34
src/main/java/com/beagle/informix/service/impl/InformixMybatisServiceImpl.java
...gle/informix/service/impl/InformixMybatisServiceImpl.java
+83
-100
src/main/resources/application.yaml
src/main/resources/application.yaml
+32
-32
src/test/java/com/beagle/informix/service/impl/InformixServiceTest.java
...com/beagle/informix/service/impl/InformixServiceTest.java
+1
-1
No files found.
pom.xml
View file @
3acd910f
...
...
@@ -58,8 +58,8 @@
</dependency>
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
druid
</artifactId>
<version>
1.2.1
5
</version>
<artifactId>
druid
-spring-boot-starter
</artifactId>
<version>
1.2.1
6
</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
...
...
@@ -93,11 +93,6 @@
<version>
RELEASE
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
com.baomidou
</groupId>
<artifactId>
mybatis-plus-core
</artifactId>
<version>
3.5.3.1
</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.dameng/DmJdbcDriver18 -->
<dependency>
<groupId>
com.dameng
</groupId>
...
...
@@ -115,12 +110,12 @@
<groupId>
com.baomidou
</groupId>
<artifactId>
mybatis-plus-boot-starter
</artifactId>
<version>
3.5.3.1
</version>
<exclusions
>
<exclusion
>
<groupId>
org.springframework.boot
</groupId
>
<artifactId>
spring-boot-starter-jdbc
</artifactId
>
</exclusion
>
</exclusions
>
<!-- <exclusions>--
>
<!-- <exclusion>--
>
<!-- <groupId>org.springframework.boot</groupId>--
>
<!-- <artifactId>spring-boot-starter-jdbc</artifactId>--
>
<!-- </exclusion>--
>
<!-- </exclusions>--
>
</dependency>
</dependencies>
...
...
src/main/java/com/beagle/informix/BaseApplication.java
View file @
3acd910f
package
com.beagle.informix
;
import
org.mybatis.spring.annotation.MapperScan
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
//import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@MapperScan
(
"com.beagle.informix"
)
//@EnableTransactionManagement(order = 2)
public
class
BaseApplication
{
...
...
src/main/java/com/beagle/informix/entity/mybatis/Vccinfo.java
View file @
3acd910f
//
package com.beagle.informix.entity.mybatis;
//
import com.baomidou.mybatisplus.annotation.IdType;
//
import com.baomidou.mybatisplus.annotation.TableField;
//
import com.baomidou.mybatisplus.annotation.TableId;
//
import com.baomidou.mybatisplus.annotation.TableName;
//
import lombok.Data;
//
import java.io.Serializable;
//
import java.sql.Blob;
//
/
//
**
//
* @author lzz
//
* date 2023/5/30
//
* @version 1.0
//
* description:
//
*/
//
@Data
//
@TableName(value = "cti_vccinfo_new")
//
public class Vccinfo implements Serializable {
//
private static final long serialVersionUID = 1L;
//
@TableId(value = "vccid", type = IdType.AUTO )
//
private Integer vId;
//
@TableField(value = "vccname")
//
private String vName;
//
@TableField(value = "effective")
//
private Integer effective;
//
@TableField(value = "agentmax")
//
private Integer agentMax;
//
@TableField(value = "ivrmax")
//
private Integer ivrMax;
//
@TableField(value = "updatekey")
//
private String updateKey;
//
@TableField(value = "tclob")
//
private String tClob;
//
/**
//
* 如果是pg等数据库,字段声明为bytea,则不需要BlobTypeHandler转换,如果声明为blob,则需要转换
//
*/
//
//
//
@TableField(value = "tblob", typeHandler = org.apache.ibatis.type.BlobTypeHandler.class)
//
@TableField(value = "tblob")
//
private byte[] tBlob;
//
}
package
com.beagle.informix.entity.mybatis
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.sql.Blob
;
/**
* @author lzz
* date 2023/5/30
* @version 1.0
* description:
*/
@Data
@TableName
(
value
=
"cti_vccinfo_new"
)
public
class
Vccinfo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
@TableId
(
value
=
"vccid"
,
type
=
IdType
.
AUTO
)
private
Integer
vId
;
@TableField
(
value
=
"vccname"
)
private
String
vName
;
@TableField
(
value
=
"effective"
)
private
Integer
effective
;
@TableField
(
value
=
"agentmax"
)
private
Integer
agentMax
;
@TableField
(
value
=
"ivrmax"
)
private
Integer
ivrMax
;
@TableField
(
value
=
"updatekey"
)
private
String
updateKey
;
@TableField
(
value
=
"tclob"
)
private
String
tClob
;
/**
* 如果是pg等数据库,字段声明为bytea,则不需要BlobTypeHandler转换,如果声明为blob,则需要转换
*/
// @TableField(value = "tblob", typeHandler = org.apache.ibatis.type.BlobTypeHandler.class)
@TableField
(
value
=
"tblob"
)
private
byte
[]
tBlob
;
}
src/main/java/com/beagle/informix/mapper/VccinfoMapper.java
View file @
3acd910f
//package com.beagle.informix.mapper;
//
//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
//import com.beagle.informix.entity.mybatis.Vccinfo;
//import org.apache.ibatis.annotations.*;
//
//import java.util.List;
//
//@Mapper
//public interface VccinfoMapper extends BaseMapper<Vccinfo> {
// @Results(
// @Result(column = "tblob",property = "tBlobStr")
// )
// @Select("SELECT * FROM cti_vccinfo_new where vccid = #{vId}")
// List<Vccinfo> queryList(@Param("vId") Integer vId);
//
// /**
// * 必须使用org.apache.ibatis.type.BlobTypeHandler转换后,才能保存到数据库
// * @param vccinfo
// */
// void insertData(@Param("vccinfo") Vccinfo vccinfo);
//}
package
com.beagle.informix.mapper
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.beagle.informix.entity.mybatis.Vccinfo
;
import
org.apache.ibatis.annotations.*
;
import
org.springframework.stereotype.Repository
;
import
java.util.List
;
@Mapper
public
interface
VccinfoMapper
extends
BaseMapper
<
Vccinfo
>
{
@Results
(
@Result
(
column
=
"tblob"
,
property
=
"tBlobStr"
)
)
@Select
(
"SELECT * FROM cti_vccinfo_new where vccid = #{vId}"
)
List
<
Vccinfo
>
queryList
(
@Param
(
"vId"
)
Integer
vId
);
/**
* 必须使用org.apache.ibatis.type.BlobTypeHandler转换后,才能保存到数据库
* @param vccinfo
*/
void
insertData
(
@Param
(
"vccinfo"
)
Vccinfo
vccinfo
);
int
selectTest
();
}
src/main/java/com/beagle/informix/service/InformixService.java
View file @
3acd910f
package
com.beagle.informix.service
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.beagle.informix.entity.mybatis.Vccinfo
;
/**
* informix(IBM)数据库测试(jdbc、hibernate、ibatis、mybatis)
*/
public
interface
InformixService
{
public
interface
InformixService
{
void
doConnectJob
()
throws
Exception
;
}
src/main/java/com/beagle/informix/service/impl/InformixJdbcProxyServiceImpl.java
View file @
3acd910f
...
...
@@ -32,6 +32,13 @@ public class InformixJdbcProxyServiceImpl implements InformixService {
this
.
resourceLoader
=
resourceLoader
;
}
public
static
void
main
(
String
[]
args
)
{
try
{
new
InformixJdbcProxyServiceImpl
(
null
).
doConnectJob
();
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
/**
* informix.url=jdbc:informix-sqli://localhost:9088/sysadmin:INFORMIXSERVER=informix
* informix.driverClassName=com.informix.jdbc.IfxDriver
...
...
@@ -44,45 +51,34 @@ public class InformixJdbcProxyServiceImpl implements InformixService {
*/
@Override
public
void
doConnectJob
()
throws
Exception
{
// todo 使用jdbc连接proxy,对应的query(clob、blob字段)存在jdbc 类型转换mysql异常的问题
// Unknown exception: Can not find JDBC type `2005` in column type
testAloneConnectionJob
();
}
private
void
testSameConnectionJob
(
Connection
connection
)
throws
Exception
{
Driver
driver
=
getDriver
();
Connection
conn
=
getConnection
(
driver
);
insert
(
conn
);
// update(conn);
// query(conn);
// delete(conn);
// 连接一直开启的话,发送的sql在proxy中都是使用一个同一个会话
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
String
querySQL
=
"SELECT 1"
;
Statement
stat
=
connection
.
createStatement
();
ResultSet
resultSet
=
stat
.
executeQuery
(
querySQL
);
}
closeConnection
(
conn
);
deregisterDriver
(
driver
);
// Unknown exception: Can not find JDBC type `2005` in column type
CompletableFuture
completableFuture
=
new
CompletableFuture
<>();
ExecutorService
executorService
=
Executors
.
newFixedThreadPool
(
500
);
// for (int i = 0; i < 1; i++) {
// try {
// Driver driver = getDriver();
// Connection conn = getConnection(driver);
// completableFuture.runAsync(()->{
// try {
// query(conn);
// }catch (Exception ee) {
// ee.printStackTrace();
// }
// }, executorService).whenComplete((v, e) -> {
// if (e != null) {
// e.printStackTrace();
// }
// try {
// closeConnection(conn);
// deregisterDriver(driver);
// }catch (Exception ex) {
// ex.printStackTrace();
// }
// });
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
// }
}
private
void
testAloneConnectionJob
()
throws
Exception
{
Driver
driver
=
getDriver
();
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
// 这种情况下的话,每次新建一个连接,在proxy中都会对应新增一个连接
Connection
conn
=
getConnection
(
driver
);
String
querySQL
=
"SELECT 1"
;
Statement
stat
=
conn
.
createStatement
();
ResultSet
resultSet
=
stat
.
executeQuery
(
querySQL
);
closeConnection
(
conn
);
}
deregisterDriver
(
driver
);
}
private
Driver
getDriver
()
throws
Exception
{
// 定义informix的驱动信息
String
driverUrl
=
"com.mysql.cj.jdbc.Driver"
;
...
...
src/main/java/com/beagle/informix/service/impl/InformixMybatisServiceImpl.java
View file @
3acd910f
//package com.beagle.informix.service.impl;
//
//import cn.hutool.json.JSONUtil;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.beagle.informix.entity.mybatis.Vccinfo;
//import com.beagle.informix.mapper.VccinfoMapper;
//import com.beagle.informix.service.InformixService;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.ibatis.annotations.Result;
//import org.apache.ibatis.annotations.Results;
//import org.springframework.core.io.ResourceLoader;
//import org.springframework.stereotype.Service;
//
//import javax.annotation.Resource;
//import javax.transaction.Transactional;
//import java.io.File;
//import java.io.FileInputStream;
//import java.sql.Connection;
//import java.sql.Driver;
//import java.util.List;
//import java.util.concurrent.CompletableFuture;
//import java.util.concurrent.ExecutorService;
//import java.util.concurrent.Executors;
//
///**
// * @author lzz
// * date 2023/5/29
// * @version 1.0
// * description:
// */
//@Service("informixMybatisService")
//@Slf4j
//public class InformixMybatisServiceImpl extends ServiceImpl<VccinfoMapper, Vccinfo> implements InformixService {
// @Resource
// private ResourceLoader resourceLoader;
// @Resource
// private VccinfoMapper vccinfoMapper;
// @Override
// @Transactional
// public void doConnectJob() throws Exception{
// CompletableFuture completableFuture = new CompletableFuture<>();
// ExecutorService executorService = Executors.newFixedThreadPool(500);
// for (int i = 0; i < 500; i++) {
// try {
//
// completableFuture.runAsync(()->{
// queryMethod();
// }, executorService).whenComplete((v, e) -> {
// if (e != null) {
// e.printStackTrace();
// }
// });
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
package
com.beagle.informix.service.impl
;
import
cn.hutool.json.JSONUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.beagle.informix.entity.mybatis.Vccinfo
;
import
com.beagle.informix.mapper.VccinfoMapper
;
import
com.beagle.informix.service.InformixService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.core.io.ResourceLoader
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.util.List
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
/**
* @author lzz
* date 2023/5/29
* @version 1.0
* description:
*/
@Service
(
"informixMybatisService"
)
@Slf4j
public
class
InformixMybatisServiceImpl
extends
ServiceImpl
<
VccinfoMapper
,
Vccinfo
>
implements
InformixService
{
@Resource
private
ResourceLoader
resourceLoader
;
@Override
public
void
doConnectJob
()
throws
Exception
{
// for (int i = 0; i < 100; i++) {
// this.baseMapper.selectTest();
// }
// }
// private void insertMethod() throws Exception{
// Vccinfo vccinfo = new Vccinfo();
// vccinfo.setVId(3);
// vccinfo.setEffective(1);
// vccinfo.setVName("mybatis");
// vccinfo.setIvrMax(1);
// vccinfo.setAgentMax(1);
// vccinfo.setUpdateKey("mybatis key");
// // 组装clob
// vccinfo.setTClob("测试clob数据!@#@Ddsfsdferewr");
// // 组装blob数据
// // 处理blob字段
// org.springframework.core.io.Resource resource = resourceLoader.getResource("classpath:EnableLoopback.exe");
// File inputStream = resource.getFile();
// try (FileInputStream fis = new FileInputStream(inputStream)){
// vccinfo.setTBlob(fis.readAllBytes());
// }
// // insert
// // 如果使用实体保存,则需要在blob字段上新增BlobTypeHandler转换
// // 如果使用xml的insert保存,也需要在属性上设置BlobTypeHandler转换
// baseMapper.insertData(vccinfo);
// }
//
// private void updateMethod() throws Exception {
// LambdaQueryWrapper<Vccinfo> queryWrapper = new LambdaQueryWrapper<>();
// queryWrapper.eq(Vccinfo::getVId, "ibatis");
// Vccinfo vccinfo = new Vccinfo();
// vccinfo.setVName("mybatis-update");
// baseMapper.update(vccinfo, queryWrapper);
// }
//
// private void queryMethod() {
// List<Vccinfo> vccinfoList = vccinfoMapper.queryList(1);
// log.info("queryAll:{}", JSONUtil.toJsonStr(vccinfoList));
// }
// private void delete() {
// LambdaQueryWrapper<Vccinfo> queryWrapper = new LambdaQueryWrapper<>();
// queryWrapper.eq(Vccinfo::getVId, "ibatis");
// baseMapper.delete(queryWrapper);
// }
//
//}
ExecutorService
executorService
=
Executors
.
newCachedThreadPool
();
for
(
int
i
=
0
;
i
<
1
;
i
++)
{
executorService
.
submit
(()->{
System
.
out
.
println
(
this
.
baseMapper
.
selectTest
());
});
}
}
private
void
insertMethod
()
throws
Exception
{
Vccinfo
vccinfo
=
new
Vccinfo
();
vccinfo
.
setVId
(
3
);
vccinfo
.
setEffective
(
1
);
vccinfo
.
setVName
(
"mybatis"
);
vccinfo
.
setIvrMax
(
1
);
vccinfo
.
setAgentMax
(
1
);
vccinfo
.
setUpdateKey
(
"mybatis key"
);
// 组装clob
vccinfo
.
setTClob
(
"测试clob数据!@#@Ddsfsdferewr"
);
// 组装blob数据
// 处理blob字段
org
.
springframework
.
core
.
io
.
Resource
resource
=
resourceLoader
.
getResource
(
"classpath:EnableLoopback.exe"
);
File
inputStream
=
resource
.
getFile
();
try
(
FileInputStream
fis
=
new
FileInputStream
(
inputStream
)){
vccinfo
.
setTBlob
(
fis
.
readAllBytes
());
}
// insert
// 如果使用实体保存,则需要在blob字段上新增BlobTypeHandler转换
// 如果使用xml的insert保存,也需要在属性上设置BlobTypeHandler转换
baseMapper
.
insertData
(
vccinfo
);
}
private
void
updateMethod
()
throws
Exception
{
LambdaQueryWrapper
<
Vccinfo
>
queryWrapper
=
new
LambdaQueryWrapper
<>();
queryWrapper
.
eq
(
Vccinfo:
:
getVId
,
"ibatis"
);
Vccinfo
vccinfo
=
new
Vccinfo
();
vccinfo
.
setVName
(
"mybatis-update"
);
baseMapper
.
update
(
vccinfo
,
queryWrapper
);
}
private
void
queryMethod
()
{
List
<
Vccinfo
>
vccinfoList
=
this
.
baseMapper
.
queryList
(
1
);
log
.
info
(
"queryAll:{}"
,
JSONUtil
.
toJsonStr
(
vccinfoList
));
}
private
void
delete
()
{
LambdaQueryWrapper
<
Vccinfo
>
queryWrapper
=
new
LambdaQueryWrapper
<>();
queryWrapper
.
eq
(
Vccinfo:
:
getVId
,
"ibatis"
);
baseMapper
.
delete
(
queryWrapper
);
}
}
src/main/resources/application.yaml
View file @
3acd910f
#spring:
# datasource:
## url: jdbc:mysql://localhost:3307/testdb?useUnicode=true&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
# url: jdbc:mysql://localhost:3307
## url: jdbc:mysql://localhost:3307/SYSDBA?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
## url: jdbc:mysql://localhost:3307/testdb?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&useServerPrepStmts=true
# username: root
# password: Apurelove9014
# type: com.alibaba.druid.pool.DruidDataSource
# druid:
# max-active: 500
# max-wait: 60000
# initial-size: 500
# connect-timeout: 30
# min-idle: 500
# min-evictable-idle-time-millis: 300000
# validation-query: select 1
# test-on-borrow: false
# test-on-return: false
# test-while-idle: false
# time-between-eviction-runs-millis: 60000
## driver-class-name: com.informix.jdbc.IfxDriver
# driver-class-name: com.mysql.jdbc.Driver # com.mysql.cj.jdbc.Driver
# jpa:
# properties:
# hibernate:
# dialect: org.hibernate.dialect.InformixDialect
# format_sql: true
#mybatis-plus:
# configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# map-underscore-to-camel-case: true
\ No newline at end of file
spring
:
datasource
:
# url: jdbc:mysql://localhost:3307/testdb?useUnicode=true&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
url
:
jdbc:mysql://localhost:3307
# url: jdbc:mysql://localhost:3307/SYSDBA?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
# url: jdbc:mysql://localhost:3307/testdb?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&useServerPrepStmts=true
username
:
root
password
:
Apurelove9014
type
:
com.alibaba.druid.pool.DruidDataSource
druid
:
max-active
:
500
max-wait
:
60000
initial-size
:
500
connect-timeout
:
30
min-idle
:
20
min-evictable-idle-time-millis
:
300000
validation-query
:
select
1
test-on-borrow
:
false
test-on-return
:
false
test-while-idle
:
false
time-between-eviction-runs-millis
:
60000
# driver-class-name: com.informix.jdbc.IfxDriver
driver-class-name
:
com.mysql.jdbc.Driver
# com.mysql.cj.jdbc.Driver
jpa
:
properties
:
hibernate
:
dialect
:
org.hibernate.dialect.InformixDialect
format_sql
:
true
mybatis-plus
:
configuration
:
log-impl
:
org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case
:
true
\ No newline at end of file
src/test/java/com/beagle/informix/service/impl/InformixServiceTest.java
View file @
3acd910f
...
...
@@ -22,7 +22,7 @@ class InformixServiceTest {
private
InformixService
informixHibernateService
;
// @Resource(name = "informixIbatisService")
// private InformixService informixIbatisService;
//
@Resource(name = "informixMybatisService")
@Resource
(
name
=
"informixMybatisService"
)
private
InformixService
informixMybatisService
;
// @Test
// void testJdbcInfo() {
...
...
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