Commit 18fa7abc authored by ZHOUYANG's avatar ZHOUYANG

提交mq

parent 42859f51
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="test1" />
</profile>
</annotationProcessing>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://maven.aliyun.com/nexus/content/repositories/central/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="f177d0e3-a97c-4e2e-abae-bdc99fc877f9" name="Default Changelist" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Class" />
</list>
</option>
</component>
<component name="MavenImportPreferences">
<option name="generalSettings">
<MavenGeneralSettings>
<option name="localRepository" value="D:\worktool\apache-maven-3.5.2\.m\repository" />
<option name="mavenHome" value="$PROJECT_DIR$/../../worktool/apache-maven-3.5.2" />
<option name="userSettingsFile" value="D:\worktool\apache-maven-3.5.2\conf\settings.xml" />
</MavenGeneralSettings>
</option>
</component>
<component name="ProjectId" id="1vhhIqyVVak7ZpRU21UsY6bTQbD" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="aspect.path.notification.shown" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/src/test/java/com/dapr" />
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.detected.package.tslint" value="true" />
<property name="node.js.selected.package.eslint" value="(autodetect)" />
<property name="node.js.selected.package.tslint" value="(autodetect)" />
<property name="project.structure.last.edited" value="Modules" />
<property name="project.structure.proportion" value="0.12706482" />
<property name="project.structure.side.proportion" value="0.2" />
<property name="settings.editor.selected.configurable" value="reference.settings.project.maven.repository.indices" />
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="D:\workpace-idea\test1\src\test\java\com\dapr" />
<recent name="D:\workpace-idea\test1\src\test\java" />
<recent name="D:\workpace-idea\test1\src\main" />
</key>
<key name="CopyClassDialog.RECENTS_KEY">
<recent name="com.pubsub" />
</key>
</component>
<component name="RunManager" selected="Application.CommonController">
<configuration name="CommonController" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="com.dapr.CommonController" />
<module name="test1" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.dapr.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="Customer" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="com.helloworld.Customer" />
<module name="test1" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.helloworld.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="PubConsumer" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="com.pubsub.PubConsumer" />
<module name="test1" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.pubsub.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="PubConsumer2" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="com.pubsub.PubConsumer2" />
<module name="test1" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.pubsub.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="PubProducer" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="com.pubsub.PubProducer" />
<module name="test1" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.pubsub.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<recent_temporary>
<list>
<item itemvalue="Application.CommonController" />
<item itemvalue="Application.PubConsumer" />
<item itemvalue="Application.PubProducer" />
<item itemvalue="Application.PubConsumer2" />
<item itemvalue="Application.Customer" />
</list>
</recent_temporary>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="f177d0e3-a97c-4e2e-abae-bdc99fc877f9" name="Default Changelist" comment="" />
<created>1627020153394</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1627020153394</updated>
<workItem from="1627020154731" duration="4193000" />
<workItem from="1628229897702" duration="224000" />
<workItem from="1628230137275" duration="13000" />
<workItem from="1635746931366" duration="9471000" />
<workItem from="1635816833956" duration="14651000" />
<workItem from="1635901216201" duration="8624000" />
<workItem from="1636075782228" duration="1028000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>test1</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>net.sourceforge.pinyin4j</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.12.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.4.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.32</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.dapr;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Map;
import java.util.TimeZone;
public class CommonController {
protected static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private final static String saveBodyTmpl="{\"content\": \"%s\"}";
protected String setBody(byte[] body, Map<String, String> headers) {
String message = body == null ? "" : new String(body, StandardCharsets.UTF_8);
Calendar utcNow = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
String utcNowAsString = DATE_FORMAT.format(utcNow.getTime());
// Handles the request by printing message.
System.out.println("Server: " + message);
return message;
}
public static String doPost(String sql) throws IOException {
String httpPort = "3500";
String resultUrl = "http://192.168.133.129:" + httpPort + "/v1.0/publish/talents-database-rabbitmq-pubsub/deathStarStatus";
// 通过httpclient发送post请求
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(resultUrl);// 创建httpPost
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-Type", "application/json");
StringEntity entity = new StringEntity(sql, "utf-8");
//System.out.println("resultUrl: " + resultUrl);
httpPost.setEntity(entity);
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httpPost);
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public static void main(String[] args) throws InterruptedException {
Thread sendThread = new Thread(new Runnable() {
public void run() {
int i=0;
while(!Thread.interrupted()){
try {
Thread.sleep(2000);
i++;
String str = "第1个线程发布--"+i;
String body=String.format(saveBodyTmpl,str);
doPost(body);
System.out.println(str);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
Thread sendThread1 = new Thread(new Runnable() {
public void run() {
int i=0;
while(!Thread.interrupted()){
try {
Thread.sleep(2000);
i++;
String str = "第2个线程发布--"+i;
String body=String.format(saveBodyTmpl,str);
doPost(body);
System.out.println(str);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
sendThread.start();
sendThread1.start();
//Thread.sleep(5*60*60*1000);
}
}
package com.dapr;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class DaprClientApplication {
private final static String saveBodyTmpl="{\"content\": \"%s\"}";
private final static String delSelBodyTmpl="{\"id\": \"%s\"}";
private final static String updateBodyTmpl="{\"id\": \"%s\", \"content\": \"%s\"}";
public static void main(String[] args) throws InterruptedException {
Thread sendThread = new Thread(new Runnable() {
public void run() {
int i=0;
//while(!Thread.interrupted()){
try {
Thread.sleep(10000);
i++;
String str = "第"+ i +"个意见~~~";
// 增
String body=String.format(saveBodyTmpl,str);
save(body);
// 改
// String body=String.format(updateBodyTmpl, String.valueOf(i), str);
// update(body);
// 删,查
// String body=String.format(delSelBodyTmpl, String.valueOf(i));
// select(body);
// delete(body);
} catch (Exception e) {
e.printStackTrace();
}
// }
}
});
sendThread.start();
Thread.sleep(5*60*60*1000);
}
private static void save(String body) throws IOException {
sendRequest(body,"save");
}
private static void update(String body) throws IOException {
sendRequest(body,"update");
}
private static void select(String body) throws IOException {
sendRequest(body,"select");
}
private static void delete(String body) throws IOException {
sendRequest(body,"delete");
}
private static void sendRequest(String body, String mothed) throws IOException {
String httpPort = System.getenv("DAPR_HTTP_PORT");
if (httpPort == null) {
httpPort = "3500";
}
String resultUrl = "http://121.43.155.15:" + httpPort + "/v1.0/invoke/java-service/method/" + mothed;
URL url = new URL(resultUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setDoInput(true);
System.out.println("request body:"+body);
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(body.getBytes("UTF-8"));
out.flush();
out.close();
connection.connect();
BufferedReader bReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String line, resultStr = "";
while (null != (line = bReader.readLine())) {
resultStr += line;
}
System.out.println(resultStr);
bReader.close();
}
}
package com.helloworld;
import com.rabbitmq.client.*;
import com.utils.RabbitMQUtils;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @program: test1
* @description: 消费消息
* @author: zhouyang
* @create: 2021-11-01 14:28
*/
public class Customer {
public static void main(String[] args) throws IOException, TimeoutException {
//通过工具类获取连接
Connection connection = RabbitMQUtils.getConnection();
//创建通道
Channel channel = connection.createChannel();
//通道绑定对象
channel.queueDeclare("hello", false, false, false, null);
//消费信息
//参数1:消费哪个队列的消息 队列名称
//参数2:开始消费的自动确认机制
//参数3:消费时的回调接口
channel.basicConsume("hello", true, new DefaultConsumer(channel) {
@Override //最后一个参数:消息队列中取出的消息
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("==========================" + new String(body));
}
});
}
}
package com.helloworld;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.utils.RabbitMQUtils;
import org.junit.Test;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @program: test1
* @description: 发布消息
* @author: zhouyang
* @create: 2021-11-01 14:26
*/
public class Provider {
//生产消息
@Test
public void testSendMessage() throws IOException, TimeoutException {
//通过工具类获取连接对象
Connection connection = RabbitMQUtils.getConnection();
//获取连接中的通道
Channel channel = connection.createChannel();
//通道绑定对应消息队列
//参数1:队列名称 如果队列不存在自动创建
//参数2:用来定义队列特性是否要持久化 true 持久化队列 false 不持久化
//参数3:exclusive 是否独占队列 true 独占队列 false 不独占
//参数4:autoDelete:是否在消费完成后自动删除队列 true 自动删除 false 不自动删除
//参数5:额外附加参数
channel.queueDeclare("hello", false, false, false, null);
//发布消息
//参数1:交换机名称 参数2:队列名称 参数3:传递消息额外设置 参数4:消息的具体内容
channel.basicPublish("", "hello", null, "hello rabbitmq".getBytes());
//调用工具类
RabbitMQUtils.closeConnectionAndChannel(channel, connection);
}
}
package com.pubsub;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @program: test1
* @description: 消费者
* @author: zhouyang
* @create: 2021-11-01 15:01
*/
public class PubConsumer {
public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.133.129");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
Connection connection = null;
Channel channel = null;
try {
//创建连接
connection = connectionFactory.newConnection("消费者");
//获取通道
channel = connection.createChannel();
//通过通道声明队列,创建交换机等一系列事情
channel.basicConsume("test_fanout_queue1", true, new DeliverCallback() {
@Override
public void handle(String s, Delivery delivery) throws IOException {
System.out.println("1号消费者接受到的消息为 " + new String(delivery.getBody(), "UTF-8"));
}
}, new CancelCallback() {
@Override
public void handle(String s) throws IOException {
System.out.println("收取消息失败");
}
});
//卡一下
System.out.println("键盘输入关闭消费者");
System.in.read();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
finally {
//关闭通道
if(channel != null && channel.isOpen()){
try {
channel.close();
}
catch (Exception e){
e.printStackTrace();
}
}
if(connection != null && connection.isOpen()){
try {
connection.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
}
}
package com.pubsub;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @program: test1
* @description: 消费者2
* @author: zhouyang
* @create: 2021-11-01 15:01
*/
public class PubConsumer2 {
public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.133.129");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
Connection connection = null;
Channel channel = null;
try {
//创建连接
connection = connectionFactory.newConnection("消费者");
//获取通道
channel = connection.createChannel();
//通过通道声明队列,创建交换机等一系列事情
channel.basicConsume("test_fanout_queue2", true, new DeliverCallback() {
@Override
public void handle(String s, Delivery delivery) throws IOException {
System.out.println("2号消费者接受到的消息为 " + new String(delivery.getBody(), "UTF-8"));
}
}, new CancelCallback() {
@Override
public void handle(String s) throws IOException {
System.out.println("收取消息失败");
}
});
//卡一下
System.out.println("键盘输入关闭消费者");
System.in.read();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
finally {
//关闭通道
if(channel != null && channel.isOpen()){
try {
channel.close();
}
catch (Exception e){
e.printStackTrace();
}
}
if(connection != null && connection.isOpen()){
try {
connection.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
}
}
package com.pubsub;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @program: test1
* @description: 生产者
* @author: zhouyang
* @create: 2021-11-01 14:41
*/
public class PubProducer {
public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.133.129");
connectionFactory.setPort(5672);
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
connectionFactory.setVirtualHost("/");
Connection connection = null;
Channel channel = null;
try {
//创建连接
connection = connectionFactory.newConnection("生产者");
//获取通道
channel = connection.createChannel();
//创建交换机以及两个队列 同时绑定关系
String exchangeName = "test_fanout";
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.FANOUT,false,false,false,null);
String queue1Name = "test_fanout_queue1";
String queue2Name = "test_fanout_queue2";
channel.queueDeclare(queue1Name,false,false,false,null);
channel.queueDeclare(queue2Name,false,false,false,null);
//绑定关系 第三个参数为routingKey 绑定规则 fanout使用""
channel.queueBind(queue1Name,exchangeName,"");
channel.queueBind(queue2Name,exchangeName,"");
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
finally {
//关闭通道
if(channel != null && channel.isOpen()){
try {
channel.close();
}
catch (Exception e){
e.printStackTrace();
}
}
if(connection != null && connection.isOpen()){
try {
connection.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
}
}
package com.utils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @program: test1
* @description: RabbitMQ中连接工具类封装
* @author: zhouyang
* @create: 2021-11-01 14:24
*/
public class RabbitMQUtils {
private static ConnectionFactory connectionFactory;
static {
//重量级资源 类加载执行只执行一次
//创建连接mq的连接工厂对象
connectionFactory = new ConnectionFactory();
//设置连接rabbitmq主机
connectionFactory.setHost("192.168.133.129");
//设置端口号
connectionFactory.setPort(5672);
//设置连接哪个虚拟主机
connectionFactory.setVirtualHost("/");
//设置访问虚拟主机的用户名和密码
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
}
//定义提供连接对象的方法
public static Connection getConnection() {
try {
return connectionFactory.newConnection();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
return null;
}
//关闭通道和关闭连接工具方法
public static void closeConnectionAndChannel(Channel channel, Connection conn) {
try {
if (channel != null) {
channel.close();
}
if (conn != null) {
conn.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment