mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-03-01 09:49:41 -05:00
Compare commits
6 Commits
develop-1.
...
develop-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eea691a5aa | ||
|
|
a249ac0cdd | ||
|
|
b82c7184b3 | ||
|
|
d3004d76c1 | ||
|
|
3ae73072ff | ||
|
|
9c5f97157a |
@@ -59,9 +59,16 @@ public interface LiveClient {
|
|||||||
/**
|
/**
|
||||||
* Use to manually invoke event
|
* Use to manually invoke event
|
||||||
*/
|
*/
|
||||||
void publishEvent(TikTokEvent event);
|
void publishEvent(TikTokEvent event);
|
||||||
|
|
||||||
void publishMessage(String base64);
|
|
||||||
|
/**
|
||||||
|
* @param webcastMessageName name of TikTok protocol-buffer message
|
||||||
|
* @param payloadBase64 protocol-buffer message bytes payload
|
||||||
|
*/
|
||||||
|
void publishMessage(String webcastMessageName, String payloadBase64);
|
||||||
|
|
||||||
|
void publishMessage(String webcastMessageName, byte[] payload);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get information about gifts
|
* Get information about gifts
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.github.jwdeveloper.tiktok;
|
package io.github.jwdeveloper.tiktok;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
|
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
|
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokReconnectingEvent;
|
import io.github.jwdeveloper.tiktok.data.events.TikTokReconnectingEvent;
|
||||||
@@ -39,10 +40,12 @@ import io.github.jwdeveloper.tiktok.listener.TikTokListenersManager;
|
|||||||
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
||||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||||
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
|
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||||
import io.github.jwdeveloper.tiktok.models.ConnectionState;
|
import io.github.jwdeveloper.tiktok.models.ConnectionState;
|
||||||
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
|
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
|
||||||
import io.github.jwdeveloper.tiktok.websocket.SocketClient;
|
import io.github.jwdeveloper.tiktok.websocket.SocketClient;
|
||||||
|
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -56,15 +59,19 @@ public class TikTokLiveClient implements LiveClient {
|
|||||||
private final TikTokListenersManager listenersManager;
|
private final TikTokListenersManager listenersManager;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private final GiftsManager giftsManager;
|
private final GiftsManager giftsManager;
|
||||||
|
private final TikTokLiveMessageHandler messageHandler;
|
||||||
|
|
||||||
public TikTokLiveClient(GiftsManager giftsManager,
|
public TikTokLiveClient(
|
||||||
TikTokRoomInfo tikTokLiveMeta,
|
TikTokLiveMessageHandler messageHandler,
|
||||||
LiveHttpClient tiktokHttpClient,
|
GiftsManager giftsManager,
|
||||||
SocketClient webSocketClient,
|
TikTokRoomInfo tikTokLiveMeta,
|
||||||
TikTokLiveEventHandler tikTokEventHandler,
|
LiveHttpClient tiktokHttpClient,
|
||||||
LiveClientSettings clientSettings,
|
SocketClient webSocketClient,
|
||||||
TikTokListenersManager listenersManager,
|
TikTokLiveEventHandler tikTokEventHandler,
|
||||||
Logger logger) {
|
LiveClientSettings clientSettings,
|
||||||
|
TikTokListenersManager listenersManager,
|
||||||
|
Logger logger) {
|
||||||
|
this.messageHandler = messageHandler;
|
||||||
this.giftsManager = giftsManager;
|
this.giftsManager = giftsManager;
|
||||||
this.liveRoomInfo = tikTokLiveMeta;
|
this.liveRoomInfo = tikTokLiveMeta;
|
||||||
this.httpClient = tiktokHttpClient;
|
this.httpClient = tiktokHttpClient;
|
||||||
@@ -184,6 +191,20 @@ public class TikTokLiveClient implements LiveClient {
|
|||||||
tikTokEventHandler.publish(this, event);
|
tikTokEventHandler.publish(this, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publishMessage(String webcastMessageName, String payloadBase64) {
|
||||||
|
this.publishMessage(webcastMessageName, Base64.getDecoder().decode(payloadBase64));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void publishMessage(String webcastMessageName, byte[] payload) {
|
||||||
|
|
||||||
|
var builder = WebcastResponse.Message.newBuilder();
|
||||||
|
builder.setMethod(webcastMessageName);
|
||||||
|
builder.setPayload(ByteString.copyFrom(payload));
|
||||||
|
var message = builder.build();
|
||||||
|
messageHandler.handleSingleMessage(this, message);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GiftsManager getGiftManager() {
|
public GiftsManager getGiftManager() {
|
||||||
return giftsManager;
|
return giftsManager;
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
|||||||
eventHandler);
|
eventHandler);
|
||||||
|
|
||||||
return new TikTokLiveClient(
|
return new TikTokLiveClient(
|
||||||
|
messageHandler,
|
||||||
giftsManager,
|
giftsManager,
|
||||||
tiktokRoomInfo,
|
tiktokRoomInfo,
|
||||||
liveHttpClient,
|
liveHttpClient,
|
||||||
|
|||||||
@@ -40,12 +40,11 @@ public class CollectorExample {
|
|||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
|
||||||
var collector = TikTokLiveCollector.use(settings ->
|
var collector = TikTokLiveCollector.useMongo(settings ->
|
||||||
{
|
{
|
||||||
settings.setConnectionUrl("mongodb+srv://" + mongoUser + ":" + mongoPassword + "@" + mongoDatabase + "/?retryWrites=true&w=majority");
|
settings.setConnectionUrl("mongodb+srv://" + mongoUser + ":" + mongoPassword + "@" + mongoDatabase + "/?retryWrites=true&w=majority");
|
||||||
settings.setDatabaseName("tiktok");
|
|
||||||
});
|
});
|
||||||
collector.connectDatabase();
|
collector.connect();
|
||||||
|
|
||||||
var users = List.of("tehila_723", "dino123597", "domaxyzx", "dash4214", "obserwacje_live");
|
var users = List.of("tehila_723", "dino123597", "domaxyzx", "dash4214", "obserwacje_live");
|
||||||
Map<String, Object> additionalDataFields = Map.of("sessionTag", "ExampleTag");
|
Map<String, Object> additionalDataFields = Map.of("sessionTag", "ExampleTag");
|
||||||
@@ -71,6 +70,6 @@ public class CollectorExample {
|
|||||||
}
|
}
|
||||||
|
|
||||||
System.in.read();
|
System.in.read();
|
||||||
collector.disconnectDatabase();
|
collector.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package io.github.jwdeveloper.tiktok;
|
package io.github.jwdeveloper.tiktok;
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokCommentEvent;
|
import io.github.jwdeveloper.tiktok.data.events.TikTokCommentEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokSubNotifyEvent;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokSubscribeEvent;
|
import io.github.jwdeveloper.tiktok.data.events.TikTokSubscribeEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
|
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||||
@@ -11,7 +10,9 @@ import io.github.jwdeveloper.tiktok.data.events.social.TikTokLikeEvent;
|
|||||||
import io.github.jwdeveloper.tiktok.data.models.gifts.GiftComboStateType;
|
import io.github.jwdeveloper.tiktok.data.models.gifts.GiftComboStateType;
|
||||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||||
|
|
||||||
public class Events_And_Gifts_Testing_Example {
|
public class Events_And_Gifts_Testing_Example
|
||||||
|
{
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
LiveClient client = TikTokLive.newClient(ConnectionExample.TIKTOK_HOSTNAME)
|
LiveClient client = TikTokLive.newClient(ConnectionExample.TIKTOK_HOSTNAME)
|
||||||
.configure(liveClientSettings ->
|
.configure(liveClientSettings ->
|
||||||
@@ -35,6 +36,10 @@ public class Events_And_Gifts_Testing_Example {
|
|||||||
{
|
{
|
||||||
liveClient.getLogger().info("New fake Gift: " + event.getGift());
|
liveClient.getLogger().info("New fake Gift: " + event.getGift());
|
||||||
})
|
})
|
||||||
|
.onLike((liveClient, event) ->
|
||||||
|
{
|
||||||
|
liveClient.getLogger().info("New fake Like event: " + event.getLikes());
|
||||||
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
var gifts = TikTokLive.gifts();
|
var gifts = TikTokLive.gifts();
|
||||||
@@ -57,11 +62,13 @@ public class Events_And_Gifts_Testing_Example {
|
|||||||
client.publishEvent(fakeMessage);
|
client.publishEvent(fakeMessage);
|
||||||
client.publishEvent(fakeSubscriber);
|
client.publishEvent(fakeSubscriber);
|
||||||
client.publishEvent(fakeFollow);
|
client.publishEvent(fakeFollow);
|
||||||
client.publishEvent(fakeLike);
|
|
||||||
client.publishEvent(fakeJoin);
|
client.publishEvent(fakeJoin);
|
||||||
|
|
||||||
|
client.publishEvent(fakeLike);
|
||||||
|
client.publishMessage("WebcastLikeMessage", webcastLikeMessageBase64);
|
||||||
|
|
||||||
client.disconnect();
|
client.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String webcastLikeMessageBase64 = "SAFSBRABGKwCUgcIAhABGKwCCv8BUAFYAbABA7gBARCflqWWo8Ha72UgzoPZhd8xQrwBGg4gkAMKCSNmZmZmZmZmZiJ/qgF6CngIhYjjgPWJv7RgGhDwnZKm8J2TjvCdk47wk4WTsgIKa3lsbGVlaGFsbPICTE1TNHdMakFCQUFBQXUyX21LNEw4WGJYa3lNaUFvZzJUTnNmVjk5N09WM2tpQ3NCTkNjYWkwcWxIcUt0Q3B0UGU1N2RLYVhxb0xWSXoICwoQcG1fbXRfbXNnX3ZpZXdlchIXezA6dXNlcn0gbGlrZWQgdGhlIExJVkVIAQoSV2ViY2FzdExpa2VNZXNzYWdlGIaWvY+RhdjvZTABwAEBEA8Y+Voq7RCyAQYImwEQjwK6AQCCAgDyAkxNUzR3TGpBQkFBQUF1Ml9tSzRMOFhiWGt5TWlBb2cyVE5zZlY5OTdPVjNraUNzQk5DY2FpMHFsSHFLdENwdFBlNTdkS2FYcW9MVkl6ggTqCLoBnwUqBggBEAEYIFoNCgASCSNCMzQ3N0VGRoABDwgEEtgEEix3ZWJjYXN0LXZhL2dyYWRlX2JhZGdlX2ljb25fbGl0ZV9sdjE1X3YyLnBuZzrpAnNzbG9jYWw6Ly93ZWJjYXN0X2x5bnh2aWV3X3BvcHVwP3VzZV9zcGFyaz0xJnVybD1odHRwcyUzQSUyRiUyRmxmMTYtZ2Vja28tc291cmNlLnRpa3Rva2Nkbi5jb20lMkZvYmolMkZieXRlLWd1cmQtc291cmNlLXNnJTJGdGlrdG9rJTJGZmUlMkZsaXZlJTJGdGlrdG9rX2xpdmVfcmV2ZW51ZV91c2VyX2xldmVsX21haW4lMkZzcmMlMkZwYWdlcyUyRnByaXZpbGVnZSUyRnBhbmVsJTJGdGVtcGxhdGUuanMmaGlkZV9zdGF0dXNfYmFyPTAmaGlkZV9uYXZfYmFyPTEmY29udGFpbmVyX2JnX2NvbG9yPTAwMDAwMDAwJmhlaWdodD05MCUyNSZiZGhtX2JpZD10aWt0b2tfbGl2ZV9yZXZlbnVlX3VzZXJfbGV2ZWxfbWFpbiZ1c2VfZm9yZXN0PTEKXWh0dHBzOi8vcDE2LXdlYmNhc3QudGlrdG9rY2RuLmNvbS93ZWJjYXN0LXZhL2dyYWRlX2JhZGdlX2ljb25fbGl0ZV9sdjE1X3YyLnBuZ350cGx2LW9iai5pbWFnZQpdaHR0cHM6Ly9wMTktd2ViY2FzdC50aWt0b2tjZG4uY29tL3dlYmNhc3QtdmEvZ3JhZGVfYmFkZ2VfaWNvbl9saXRlX2x2MTVfdjIucG5nfnRwbHYtb2JqLmltYWdlIgIxNTIAOgYaAhIAIgBiDQoAEgkjQjM0NzdFRkZ4DqIBBggBEAEYIAgEEBQYCCABUukCc3Nsb2NhbDovL3dlYmNhc3RfbHlueHZpZXdfcG9wdXA/dXNlX3NwYXJrPTEmdXJsPWh0dHBzJTNBJTJGJTJGbGYxNi1nZWNrby1zb3VyY2UudGlrdG9rY2RuLmNvbSUyRm9iaiUyRmJ5dGUtZ3VyZC1zb3VyY2Utc2clMkZ0aWt0b2slMkZmZSUyRmxpdmUlMkZ0aWt0b2tfbGl2ZV9yZXZlbnVlX3VzZXJfbGV2ZWxfbWFpbiUyRnNyYyUyRnBhZ2VzJTJGcHJpdmlsZWdlJTJGcGFuZWwlMkZ0ZW1wbGF0ZS5qcyZoaWRlX3N0YXR1c19iYXI9MCZoaWRlX25hdl9iYXI9MSZjb250YWluZXJfYmdfY29sb3I9MDAwMDAwMDAmaGVpZ2h0PTkwJTI1JmJkaG1fYmlkPXRpa3Rva19saXZlX3JldmVudWVfdXNlcl9sZXZlbF9tYWluJnVzZV9mb3Jlc3Q9MVgBYk8qAjE1CgEyEhM3MTM4MzgxNzQ3MjkyNTQyNzU2GgEwIi5tb2NrX2ZpeF93aWR0aF90cmFuc3BhcmVudF83MTM4MzgxNzQ3MjkyNTQyNzU2CIWI44D1ib+0YBoQ8J2SpvCdk47wnZOO8JOFk0r1BhJBMTAweDEwMC90b3MtdXNlYXN0OC1hdnQtMDA2OC10eDIvNjY0NmM4NjZjMzI1MWEwOTY3NjhiYjY4OTUyODVjMzEK0gFodHRwczovL3AxOS1wdS1zaWduLXVzZWFzdDgudGlrdG9rY2RuLXVzLmNvbS90b3MtdXNlYXN0OC1hdnQtMDA2OC10eDIvNjY0NmM4NjZjMzI1MWEwOTY3NjhiYjY4OTUyODVjMzF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/bGszcz1hNWQ0ODA3OCZ4LWV4cGlyZXM9MTcwOTMxMjQwMCZ4LXNpZ25hdHVyZT1VMlNEbUk3Z3R5RW9rMlBlWFdmeTNsM1F6NlElM0QKyAFodHRwczovL3AxNi1wdS1zaWduLXVzZWFzdDgudGlrdG9rY2RuLXVzLmNvbS90b3MtdXNlYXN0OC1hdnQtMDA2OC10eDIvNjY0NmM4NjZjMzI1MWEwOTY3NjhiYjY4OTUyODVjMzF+YzVfMTAweDEwMC53ZWJwP2xrM3M9YTVkNDgwNzgmeC1leHBpcmVzPTE3MDkzMTI0MDAmeC1zaWduYXR1cmU9aWNWZEVZa0FnWkYlMkZ2WU5OTSUyRlVNMzE2eG9HdyUzRArGAWh0dHBzOi8vcDE5LXB1LXNpZ24tdXNlYXN0OC50aWt0b2tjZG4tdXMuY29tL3Rvcy11c2Vhc3Q4LWF2dC0wMDY4LXR4Mi82NjQ2Yzg2NmMzMjUxYTA5Njc2OGJiNjg5NTI4NWMzMX5jNV8xMDB4MTAwLndlYnA/bGszcz1hNWQ0ODA3OCZ4LWV4cGlyZXM9MTcwOTMxMjQwMCZ4LXNpZ25hdHVyZT1PQzdBQ3htQUklMkJsYlp4RkVuWktJT1RyRExGUSUzRArGAWh0dHBzOi8vcDE2LXB1LXNpZ24tdXNlYXN0OC50aWt0b2tjZG4tdXMuY29tL3Rvcy11c2Vhc3Q4LWF2dC0wMDY4LXR4Mi82NjQ2Yzg2NmMzMjUxYTA5Njc2OGJiNjg5NTI4NWMzMX5jNV8xMDB4MTAwLmpwZWc/bGszcz1hNWQ0ODA3OCZ4LWV4cGlyZXM9MTcwOTMxMjQwMCZ4LXNpZ25hdHVyZT02YUwlMkZNZWtOeHg5NXlvVTVLOTZON0xwRUlNdyUzRLICCmt5bGxlZWhhbGxCyQEIgojG1pKb0clgErwBChBwbV9tdF9tc2dfdmlld2VyEhd7MDp1c2VyfSBsaWtlZCB0aGUgTElWRRoOCgkjZmZmZmZmZmYgkAMifwgLqgF6CngIhYjjgPWJv7RgGhDwnZKm8J2TjvCdk47wk4WTsgIKa3lsbGVlaGFsbPICTE1TNHdMakFCQUFBQXUyX21LNEw4WGJYa3lNaUFvZzJUTnNmVjk5N09WM2tpQ3NCTkNjYWkwcWxIcUt0Q3B0UGU1N2RLYVhxb0xWSXo=";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,19 +22,34 @@
|
|||||||
*/
|
*/
|
||||||
package io.github.jwdeveloper.tiktok.extension.collector;
|
package io.github.jwdeveloper.tiktok.extension.collector;
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.extension.collector.api.LiveDataCollector;
|
import io.github.jwdeveloper.tiktok.extension.collector.api.settings.FileDataCollectorSettings;
|
||||||
import io.github.jwdeveloper.tiktok.extension.collector.api.data.LiveDataCollectorSettings;
|
import io.github.jwdeveloper.tiktok.extension.collector.api.settings.mongo.MongoDataCollectorSettings;
|
||||||
import io.github.jwdeveloper.tiktok.extension.collector.impl.TikTokLiveDataCollector;
|
import io.github.jwdeveloper.tiktok.extension.collector.impl.*;
|
||||||
|
import io.github.jwdeveloper.tiktok.extension.collector.impl.storages.FileStorage;
|
||||||
|
import io.github.jwdeveloper.tiktok.extension.collector.impl.storages.MongoStorage;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class TikTokLiveCollector
|
public class TikTokLiveCollector
|
||||||
{
|
{
|
||||||
|
|
||||||
public static TikTokLiveDataCollector use(Consumer<LiveDataCollectorSettings> consumer)
|
public static DataCollector useMongo(Consumer<MongoDataCollectorSettings> consumer) {
|
||||||
{
|
var settings = new MongoDataCollectorSettings();
|
||||||
var settings = new LiveDataCollectorSettings();
|
|
||||||
consumer.accept(settings);
|
consumer.accept(settings);
|
||||||
return new TikTokLiveDataCollector(settings);
|
|
||||||
|
var storage = new MongoStorage(settings);
|
||||||
|
return new DataCollector(storage);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static DataCollector useFile(Consumer<FileDataCollectorSettings> consumer) {
|
||||||
|
var settings = new FileDataCollectorSettings();
|
||||||
|
consumer.accept(settings);
|
||||||
|
|
||||||
|
var storage = new FileStorage(settings);
|
||||||
|
return new DataCollector(storage);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.extension.collector.api;
|
||||||
|
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
|
public interface Storage {
|
||||||
|
void connect();
|
||||||
|
|
||||||
|
void disconnect();
|
||||||
|
|
||||||
|
void insert(Document document);
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.github.jwdeveloper.tiktok.extension.collector.api.data;
|
package io.github.jwdeveloper.tiktok.extension.collector.api.settings;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
@@ -10,4 +10,4 @@ import java.util.function.Function;
|
|||||||
public class CollectorListenerSettings {
|
public class CollectorListenerSettings {
|
||||||
private Map<String, Object> extraFields;
|
private Map<String, Object> extraFields;
|
||||||
private Function<Document, Boolean> filter;
|
private Function<Document, Boolean> filter;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package io.github.jwdeveloper.tiktok.extension.collector.api.settings;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FileDataCollectorSettings {
|
||||||
|
|
||||||
|
private File parentFile;
|
||||||
|
}
|
||||||
@@ -20,36 +20,21 @@
|
|||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package io.github.jwdeveloper.tiktok.extension.collector.api.data;
|
package io.github.jwdeveloper.tiktok.extension.collector.api.settings.mongo;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Accessors(chain = true)
|
||||||
public class MongoDBConnectionStringBuilder {
|
public class MongoDBConnectionStringBuilder {
|
||||||
private String username;
|
private String username;
|
||||||
private String password;
|
private String password;
|
||||||
private String database;
|
private String database;
|
||||||
private String cluster;
|
private String cluster;
|
||||||
|
|
||||||
public MongoDBConnectionStringBuilder setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoDBConnectionStringBuilder setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoDBConnectionStringBuilder setDatabase(String database) {
|
|
||||||
this.database = database;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoDBConnectionStringBuilder setCluster(String cluster) {
|
|
||||||
this.cluster = cluster;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String build() {
|
public String build() {
|
||||||
return String.format("mongodb+srv://%s:%s@%s/%s?retryWrites=true&w=majority",
|
return String.format("mongodb+srv://%s:%s@%s/%s?retryWrites=true&w=majority",
|
||||||
username, password, cluster, database);
|
username, password, cluster, database);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,29 +20,25 @@
|
|||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package io.github.jwdeveloper.tiktok.extension.collector.api.data;
|
package io.github.jwdeveloper.tiktok.extension.collector.api.settings.mongo;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.*;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class LiveDataCollectorSettings {
|
public class MongoDataCollectorSettings {
|
||||||
|
|
||||||
|
@Setter
|
||||||
private String connectionUrl;
|
private String connectionUrl;
|
||||||
|
|
||||||
private String databaseName;
|
private String databaseName = "tiktok";
|
||||||
|
|
||||||
private String sessionTag;
|
private String collectionName = "data";
|
||||||
|
|
||||||
|
public void connectionBuilder(Consumer<MongoDBConnectionStringBuilder> consumer) {
|
||||||
public void setConnectionUrl(String connectionUrl) {
|
|
||||||
this.connectionUrl = connectionUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConnectionUrl(Consumer<MongoDBConnectionStringBuilder> consumer) {
|
|
||||||
var builder = new MongoDBConnectionStringBuilder();
|
var builder = new MongoDBConnectionStringBuilder();
|
||||||
consumer.accept(builder);
|
consumer.accept(builder);
|
||||||
connectionUrl = builder.build();
|
connectionUrl = builder.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package io.github.jwdeveloper.tiktok.extension.collector.impl;
|
||||||
|
|
||||||
|
import io.github.jwdeveloper.tiktok.extension.collector.api.Storage;
|
||||||
|
import io.github.jwdeveloper.tiktok.extension.collector.api.settings.CollectorListenerSettings;
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class DataCollector {
|
||||||
|
|
||||||
|
private final Storage storage;
|
||||||
|
|
||||||
|
public DataCollector(Storage storage) {
|
||||||
|
this.storage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect() {
|
||||||
|
storage.connect();
|
||||||
|
}
|
||||||
|
public void disconnect() {
|
||||||
|
storage.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataCollectorListener newListener() {
|
||||||
|
return newListener(Map.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataCollectorListener newListener(Map<String, Object> additionalFields) {
|
||||||
|
return newListener(additionalFields, (e) -> true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataCollectorListener newListener(Map<String, Object> additionalFields,
|
||||||
|
Function<Document, Boolean> filter) {
|
||||||
|
var settings = new CollectorListenerSettings();
|
||||||
|
settings.setExtraFields(additionalFields);
|
||||||
|
settings.setFilter(filter);
|
||||||
|
return new DataCollectorListener(storage, settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package io.github.jwdeveloper.tiktok.extension.collector.impl;
|
package io.github.jwdeveloper.tiktok.extension.collector.impl;
|
||||||
|
|
||||||
import com.mongodb.client.MongoCollection;
|
|
||||||
import io.github.jwdeveloper.tiktok.annotations.TikTokEventObserver;
|
import io.github.jwdeveloper.tiktok.annotations.TikTokEventObserver;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
|
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||||
@@ -8,7 +7,8 @@ import io.github.jwdeveloper.tiktok.data.events.control.TikTokConnectingEvent;
|
|||||||
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketResponseEvent;
|
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketResponseEvent;
|
||||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
|
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
|
||||||
import io.github.jwdeveloper.tiktok.extension.collector.api.LiveDataCollector;
|
import io.github.jwdeveloper.tiktok.extension.collector.api.LiveDataCollector;
|
||||||
import io.github.jwdeveloper.tiktok.extension.collector.api.data.CollectorListenerSettings;
|
import io.github.jwdeveloper.tiktok.extension.collector.api.Storage;
|
||||||
|
import io.github.jwdeveloper.tiktok.extension.collector.api.settings.CollectorListenerSettings;
|
||||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||||
import io.github.jwdeveloper.tiktok.utils.JsonUtil;
|
import io.github.jwdeveloper.tiktok.utils.JsonUtil;
|
||||||
@@ -19,15 +19,15 @@ import java.io.StringWriter;
|
|||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class TikTokLiveDataCollectorListener implements LiveDataCollector {
|
public class DataCollectorListener implements LiveDataCollector {
|
||||||
|
|
||||||
private final MongoCollection<Document> collection;
|
private final Storage storage;
|
||||||
private final CollectorListenerSettings settings;
|
private final CollectorListenerSettings settings;
|
||||||
private String sessionId;
|
private String sessionId;
|
||||||
private String userName;
|
private String userName;
|
||||||
|
|
||||||
public TikTokLiveDataCollectorListener(MongoCollection<Document> collection, CollectorListenerSettings settings) {
|
public DataCollectorListener(Storage collection, CollectorListenerSettings settings) {
|
||||||
this.collection = collection;
|
this.storage = collection;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,10 +35,7 @@ public class TikTokLiveDataCollectorListener implements LiveDataCollector {
|
|||||||
@TikTokEventObserver
|
@TikTokEventObserver
|
||||||
private void onResponse(LiveClient liveClient, TikTokWebsocketResponseEvent event) {
|
private void onResponse(LiveClient liveClient, TikTokWebsocketResponseEvent event) {
|
||||||
includeResponse(liveClient, event.getResponse());
|
includeResponse(liveClient, event.getResponse());
|
||||||
event.getResponse().getMessagesList().forEach(message ->
|
event.getResponse().getMessagesList().forEach(message -> includeMessage(liveClient, message));
|
||||||
{
|
|
||||||
includeMessage(liveClient, message);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TikTokEventObserver
|
@TikTokEventObserver
|
||||||
@@ -103,7 +100,7 @@ public class TikTokLiveDataCollectorListener implements LiveDataCollector {
|
|||||||
if (!settings.getFilter().apply(document)) {
|
if (!settings.getFilter().apply(document)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
collection.insertOne(document);
|
storage.insert(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -119,4 +116,4 @@ public class TikTokLiveDataCollectorListener implements LiveDataCollector {
|
|||||||
doc.append("content", content);
|
doc.append("content", content);
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.extension.collector.impl;
|
|
||||||
|
|
||||||
import com.mongodb.ConnectionString;
|
|
||||||
import com.mongodb.MongoClientSettings;
|
|
||||||
import com.mongodb.ServerApi;
|
|
||||||
import com.mongodb.ServerApiVersion;
|
|
||||||
import com.mongodb.client.MongoClient;
|
|
||||||
import com.mongodb.client.MongoClients;
|
|
||||||
import com.mongodb.client.MongoCollection;
|
|
||||||
import com.mongodb.client.MongoDatabase;
|
|
||||||
import com.mongodb.client.model.Indexes;
|
|
||||||
import io.github.jwdeveloper.tiktok.extension.collector.api.data.CollectorListenerSettings;
|
|
||||||
import io.github.jwdeveloper.tiktok.extension.collector.api.data.LiveDataCollectorSettings;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class TikTokLiveDataCollector {
|
|
||||||
|
|
||||||
private final LiveDataCollectorSettings settings;
|
|
||||||
private MongoClient mongoClient;
|
|
||||||
private MongoDatabase database;
|
|
||||||
private MongoCollection<Document> collection;
|
|
||||||
|
|
||||||
public TikTokLiveDataCollector(LiveDataCollectorSettings settings) {
|
|
||||||
this.settings = settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connectDatabase() {
|
|
||||||
var serverApi = ServerApi.builder()
|
|
||||||
.version(ServerApiVersion.V1)
|
|
||||||
.build();
|
|
||||||
var mongoSettings = MongoClientSettings.builder()
|
|
||||||
.applyConnectionString(new ConnectionString(settings.getConnectionUrl()))
|
|
||||||
.serverApi(serverApi)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
mongoClient = MongoClients.create(mongoSettings);
|
|
||||||
database = mongoClient.getDatabase(settings.getDatabaseName());
|
|
||||||
collection = database.getCollection("data");
|
|
||||||
collection.createIndex(Indexes.hashed("session"));
|
|
||||||
collection.createIndex(Indexes.hashed("dataType"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void disconnectDatabase() {
|
|
||||||
mongoClient.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TikTokLiveDataCollectorListener newListener() {
|
|
||||||
return newListener(Map.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
public TikTokLiveDataCollectorListener newListener(Map<String, Object> additionalFields) {
|
|
||||||
return newListener(additionalFields, (e)->true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TikTokLiveDataCollectorListener newListener(Map<String, Object> additionalFields,
|
|
||||||
Function<Document, Boolean> filter) {
|
|
||||||
var settings = new CollectorListenerSettings();
|
|
||||||
settings.setExtraFields(additionalFields);
|
|
||||||
settings.setFilter(filter);
|
|
||||||
return new TikTokLiveDataCollectorListener(collection, settings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.extension.collector.impl.storages;
|
||||||
|
|
||||||
|
import io.github.jwdeveloper.tiktok.extension.collector.api.Storage;
|
||||||
|
import io.github.jwdeveloper.tiktok.extension.collector.api.settings.FileDataCollectorSettings;
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
|
||||||
|
public class FileStorage implements Storage {
|
||||||
|
|
||||||
|
private final FileDataCollectorSettings settings;
|
||||||
|
|
||||||
|
public FileStorage(FileDataCollectorSettings fileDataCollectorSettings) {
|
||||||
|
this.settings = fileDataCollectorSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connect() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disconnect() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insert(Document document) {
|
||||||
|
var fileName = document.get("dataType") + ":" + document.get("dataTypeName") + ".json";
|
||||||
|
try {
|
||||||
|
var file = new File(settings.getParentFile(), fileName);
|
||||||
|
file.createNewFile();
|
||||||
|
Files.writeString(file.toPath(), document.toJson(), StandardOpenOption.APPEND);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.extension.collector.impl.storages;
|
||||||
|
|
||||||
|
import com.mongodb.ConnectionString;
|
||||||
|
import com.mongodb.MongoClientSettings;
|
||||||
|
import com.mongodb.ServerApi;
|
||||||
|
import com.mongodb.ServerApiVersion;
|
||||||
|
import com.mongodb.client.MongoClient;
|
||||||
|
import com.mongodb.client.MongoClients;
|
||||||
|
import com.mongodb.client.MongoCollection;
|
||||||
|
import com.mongodb.client.MongoDatabase;
|
||||||
|
import com.mongodb.client.model.Indexes;
|
||||||
|
import io.github.jwdeveloper.tiktok.extension.collector.api.Storage;
|
||||||
|
import io.github.jwdeveloper.tiktok.extension.collector.api.settings.mongo.MongoDataCollectorSettings;
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
|
public class MongoStorage implements Storage {
|
||||||
|
private MongoClient mongoClient;
|
||||||
|
private MongoDatabase database;
|
||||||
|
private MongoCollection<Document> collection;
|
||||||
|
private final MongoDataCollectorSettings settings;
|
||||||
|
|
||||||
|
public MongoStorage(MongoDataCollectorSettings settings) {
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connect() {
|
||||||
|
|
||||||
|
var serverApi = ServerApi.builder()
|
||||||
|
.version(ServerApiVersion.V1)
|
||||||
|
.build();
|
||||||
|
var mongoSettings = MongoClientSettings.builder()
|
||||||
|
.applyConnectionString(new ConnectionString(settings.getConnectionUrl()))
|
||||||
|
.serverApi(serverApi)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
mongoClient = MongoClients.create(mongoSettings);
|
||||||
|
database = mongoClient.getDatabase(settings.getDatabaseName());
|
||||||
|
collection = database.getCollection(settings.getCollectionName());
|
||||||
|
collection.createIndex(Indexes.hashed("session"));
|
||||||
|
collection.createIndex(Indexes.hashed("dataType"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disconnect() {
|
||||||
|
|
||||||
|
if (mongoClient == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mongoClient.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insert(Document document) {
|
||||||
|
collection.insertOne(document);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user