Use a unique instance ID for pinging home (#566)
* Use a unique instance ID for pinging home * Fix event name
This commit is contained in:
parent
437eb05f19
commit
19bd7d272a
|
|
@ -1,6 +1,7 @@
|
||||||
package com.appsmith.server.domains;
|
package com.appsmith.server.domains;
|
||||||
|
|
||||||
import com.appsmith.external.models.BaseDomain;
|
import com.appsmith.external.models.BaseDomain;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
@ -12,6 +13,7 @@ import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
@Setter
|
@Setter
|
||||||
@ToString
|
@ToString
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
@Document
|
@Document
|
||||||
public class Config extends BaseDomain {
|
public class Config extends BaseDomain {
|
||||||
JSONObject config;
|
JSONObject config;
|
||||||
|
|
|
||||||
|
|
@ -916,4 +916,12 @@ public class DatabaseChangelog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ChangeSet(order = "025", id = "generate-unique-id-for-instance", author = "")
|
||||||
|
public void generateUniqueIdForInstance(MongoTemplate mongoTemplate) {
|
||||||
|
mongoTemplate.insert(new Config(
|
||||||
|
new JSONObject(Map.of("value", new ObjectId().toHexString())),
|
||||||
|
"instance-id"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.appsmith.server.solutions;
|
package com.appsmith.server.solutions;
|
||||||
|
|
||||||
|
import com.appsmith.server.services.ConfigService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
|
@ -19,28 +21,38 @@ import java.util.Map;
|
||||||
@Component
|
@Component
|
||||||
@ConditionalOnProperty(prefix = "is", name = "self-hosted")
|
@ConditionalOnProperty(prefix = "is", name = "self-hosted")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class PingScheduledTask {
|
public class PingScheduledTask {
|
||||||
|
|
||||||
|
private final ConfigService configService;
|
||||||
|
|
||||||
public static final URI GET_IP_URI = URI.create("https://api6.ipify.org");
|
public static final URI GET_IP_URI = URI.create("https://api6.ipify.org");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the external IP address of this server and pings a data point to indicate that this server instance is live.
|
* Gets the external IP address of this server and pings a data point to indicate that this server instance is live.
|
||||||
|
* We use an initial delay of two minutes to roughly wait for the application along with the migrations are finished
|
||||||
|
* and ready.
|
||||||
*/
|
*/
|
||||||
// Number of milliseconds between the start of each scheduled calls to this method.
|
// Number of milliseconds between the start of each scheduled calls to this method.
|
||||||
@Scheduled(fixedRate = 6 * 60 * 60 * 1000 /* six hours */)
|
@Scheduled(initialDelay = 2 * 60 * 1000 /* two minutes */, fixedRate = 6 * 60 * 60 * 1000 /* six hours */)
|
||||||
public void pingSchedule() {
|
public void pingSchedule() {
|
||||||
getInstallationId()
|
Mono.zip(getInstanceId(), getAddress())
|
||||||
.flatMap(this::doPing)
|
.flatMap(tuple -> doPing(tuple.getT1(), tuple.getT2()))
|
||||||
.doOnError(error -> log.debug("Error pinging home", error))
|
|
||||||
.subscribeOn(Schedulers.single())
|
.subscribeOn(Schedulers.single())
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Mono<String> getInstanceId() {
|
||||||
|
return configService.getByName("instance-id")
|
||||||
|
.map(config -> config.getConfig().getAsString("value"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method hits an API endpoint that returns the external IP address of this server instance.
|
* This method hits an API endpoint that returns the external IP address of this server instance.
|
||||||
|
*
|
||||||
* @return A publisher that yields the IP address.
|
* @return A publisher that yields the IP address.
|
||||||
*/
|
*/
|
||||||
private Mono<String> getInstallationId() {
|
private Mono<String> getAddress() {
|
||||||
return WebClient
|
return WebClient
|
||||||
.create()
|
.create()
|
||||||
.get()
|
.get()
|
||||||
|
|
@ -52,10 +64,12 @@ public class PingScheduledTask {
|
||||||
/**
|
/**
|
||||||
* Given a unique ID (called a `userId` here), this method hits the Segment API to save a data point on this server
|
* Given a unique ID (called a `userId` here), this method hits the Segment API to save a data point on this server
|
||||||
* instance being live.
|
* instance being live.
|
||||||
* @param userId A unique identifier for this server instance (usually, the external IP address of the server).
|
*
|
||||||
|
* @param instanceId A unique identifier for this server instance, usually generated at the server's first start.
|
||||||
|
* @param ipAddress The external IP address of this instance's machine.
|
||||||
* @return A publisher that yields the string response of recording the data point.
|
* @return A publisher that yields the string response of recording the data point.
|
||||||
*/
|
*/
|
||||||
private Mono<String> doPing(String userId) {
|
private Mono<String> doPing(String instanceId, String ipAddress) {
|
||||||
// Note: Hard-coding Segment auth header and the event name intentionally. These are not intended to be
|
// Note: Hard-coding Segment auth header and the event name intentionally. These are not intended to be
|
||||||
// environment specific values, instead, they are common values for all self-hosted environments. As such, they
|
// environment specific values, instead, they are common values for all self-hosted environments. As such, they
|
||||||
// are not intended to be configurable.
|
// are not intended to be configurable.
|
||||||
|
|
@ -66,7 +80,9 @@ public class PingScheduledTask {
|
||||||
.header("Authorization", "Basic QjJaM3hXRThXdDRwYnZOWDRORnJPNWZ3VXdnYWtFbk06")
|
.header("Authorization", "Basic QjJaM3hXRThXdDRwYnZOWDRORnJPNWZ3VXdnYWtFbk06")
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.body(BodyInserters.fromValue(Map.of(
|
.body(BodyInserters.fromValue(Map.of(
|
||||||
"userId", userId,
|
"userId", instanceId,
|
||||||
|
"context", Map.of("ip", ipAddress),
|
||||||
|
"properties", Map.of("ip", ipAddress),
|
||||||
"event", "Instance Active"
|
"event", "Instance Active"
|
||||||
)))
|
)))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user