Merge branch 'app-subscription-fix-2' into 'master'

Fix schedule app installation not working issue

See merge request entgra/carbon-device-mgt!758
revert-70ac1926
Inosh Perara 4 years ago
commit a36d5b39f1

@ -24,7 +24,7 @@ import java.sql.Timestamp;
public class DeviceSubscriptionData { public class DeviceSubscriptionData {
private String action; private String action;
private Timestamp actionTriggeredTimestamp; private long actionTriggeredTimestamp;
private String actionTriggeredBy; private String actionTriggeredBy;
private String actionType; private String actionType;
private String status; private String status;
@ -38,11 +38,11 @@ public class DeviceSubscriptionData {
this.action = action; this.action = action;
} }
public Timestamp getActionTriggeredTimestamp() { public long getActionTriggeredTimestamp() {
return actionTriggeredTimestamp; return actionTriggeredTimestamp;
} }
public void setActionTriggeredTimestamp(Timestamp actionTriggeredTimestamp) { public void setActionTriggeredTimestamp(long actionTriggeredTimestamp) {
this.actionTriggeredTimestamp = actionTriggeredTimestamp; this.actionTriggeredTimestamp = actionTriggeredTimestamp;
} }

@ -69,7 +69,7 @@ public class ScheduledSubscriptionDTO {
/** /**
* Scheduled time of subscription. * Scheduled time of subscription.
*/ */
private LocalDateTime scheduledAt; private long scheduledAt;
/** /**
* Username of the scheduler. * Username of the scheduler.
@ -86,7 +86,7 @@ public class ScheduledSubscriptionDTO {
} }
public ScheduledSubscriptionDTO(String taskName, String applicationUUID, LocalDateTime scheduledAt, public ScheduledSubscriptionDTO(String taskName, String applicationUUID, long scheduledAt,
List<?> subscriberList, String scheduledBy) { List<?> subscriberList, String scheduledBy) {
this.taskName = taskName; this.taskName = taskName;
this.applicationUUID = applicationUUID; this.applicationUUID = applicationUUID;
@ -135,11 +135,11 @@ public class ScheduledSubscriptionDTO {
this.status = status; this.status = status;
} }
public LocalDateTime getScheduledAt() { public long getScheduledAt() {
return scheduledAt; return scheduledAt;
} }
public void setScheduledAt(LocalDateTime scheduledAt) { public void setScheduledAt(long scheduledAt) {
this.scheduledAt = scheduledAt; this.scheduledAt = scheduledAt;
} }

@ -124,7 +124,7 @@ public interface SubscriptionDAO {
* @param scheduledBy username of the user who scheduled the subscription * @param scheduledBy username of the user who scheduled the subscription
* @throws ApplicationManagementDAOException if error occurred while updating the entry * @throws ApplicationManagementDAOException if error occurred while updating the entry
*/ */
boolean updateScheduledSubscription(int id, LocalDateTime scheduledAt, String scheduledBy) boolean updateScheduledSubscription(int id, long scheduledAt, String scheduledBy)
throws ApplicationManagementDAOException; throws ApplicationManagementDAOException;
/** /**

@ -765,7 +765,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
stmt.setString(2, subscriptionDTO.getApplicationUUID()); stmt.setString(2, subscriptionDTO.getApplicationUUID());
stmt.setString(3, subscriptionDTO.getSubscribersString()); stmt.setString(3, subscriptionDTO.getSubscribersString());
stmt.setString(4, ExecutionStatus.PENDING.toString()); stmt.setString(4, ExecutionStatus.PENDING.toString());
stmt.setTimestamp(5, Timestamp.valueOf(subscriptionDTO.getScheduledAt())); stmt.setLong(5, subscriptionDTO.getScheduledAt());
stmt.setTimestamp(6, new Timestamp(calendar.getTime().getTime())); stmt.setTimestamp(6, new Timestamp(calendar.getTime().getTime()));
stmt.setString(7, subscriptionDTO.getScheduledBy()); stmt.setString(7, subscriptionDTO.getScheduledBy());
stmt.setBoolean(8, false); stmt.setBoolean(8, false);
@ -785,7 +785,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
} }
@Override @Override
public boolean updateScheduledSubscription(int id, LocalDateTime scheduledAt, String scheduledBy) public boolean updateScheduledSubscription(int id, long scheduledAt, String scheduledBy)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION " String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION "
+ "SET " + "SET "
@ -797,7 +797,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
stmt.setTimestamp(1, Timestamp.valueOf(scheduledAt)); stmt.setLong(1, scheduledAt);
stmt.setString(2, scheduledBy); stmt.setString(2, scheduledBy);
stmt.setTimestamp(3, new Timestamp(calendar.getTime().getTime())); stmt.setTimestamp(3, new Timestamp(calendar.getTime().getTime()));
stmt.setInt(4, id); stmt.setInt(4, id);

@ -1392,12 +1392,12 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED); deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED);
deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy()); deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy());
deviceSubscriptionData deviceSubscriptionData
.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp()); .setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000);
} else { } else {
deviceSubscriptionData.setAction(Constants.SUBSCRIBED); deviceSubscriptionData.setAction(Constants.SUBSCRIBED);
deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy()); deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy());
deviceSubscriptionData deviceSubscriptionData
.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); .setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000);
} }
deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom()); deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom());
deviceSubscriptionData.setStatus(subscription.getStatus()); deviceSubscriptionData.setStatus(subscription.getStatus());

@ -40,7 +40,7 @@ public class ScheduledAppSubscriptionCleanupTask extends RandomlyAssignedSchedul
@Override @Override
public void executeRandomlyAssignedTask() { public void executeRandomlyAssignedTask() {
try { try {
if(super.isQualifiedToExecuteTask()) { if(isQualifiedToExecuteTask()) {
subscriptionManager.cleanScheduledSubscriptions(); subscriptionManager.cleanScheduledSubscriptions();
} }
} catch (SubscriptionManagementException e) { } catch (SubscriptionManagementException e) {

@ -68,7 +68,7 @@ public class ScheduledAppSubscriptionTask extends RandomlyAssignedScheduleTask {
@Override @Override
public void executeRandomlyAssignedTask() { public void executeRandomlyAssignedTask() {
if(super.isQualifiedToExecuteTask()) { if(isQualifiedToExecuteTask()) {
try { try {
ScheduledSubscriptionDTO subscriptionDTO = subscriptionManager.getPendingScheduledSubscription( ScheduledSubscriptionDTO subscriptionDTO = subscriptionManager.getPendingScheduledSubscription(
this.taskName); this.taskName);

@ -40,6 +40,8 @@ import org.wso2.carbon.ntask.core.service.TaskService;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.TextStyle; import java.time.format.TextStyle;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -64,24 +66,27 @@ public class ScheduledAppSubscriptionTaskManager {
* either {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is * either {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is
* equal to DEVICE or {@link String} if {@param subType} is USER, ROLE or GROUP * equal to DEVICE or {@link String} if {@param subType} is USER, ROLE or GROUP
* @param subscriptionType subscription type. E.g. <code>DEVICE, USER, ROLE, GROUP</code> * @param subscriptionType subscription type. E.g. <code>DEVICE, USER, ROLE, GROUP</code>
* {@see {@link org.wso2.carbon.device.application.mgt.common.SubscriptionType}} * {@see {@link SubscriptionType}}
* @param action action subscription action. E.g. {@code INSTALL/UNINSTALL} * @param action action subscription action. E.g. {@code INSTALL/UNINSTALL}
* {@see {@link org.wso2.carbon.device.application.mgt.common.SubAction}} * {@see {@link SubAction}}
* @param timestamp timestamp to schedule the application subscription * @param timestamp timestamp to schedule the application subscription
* @throws ApplicationOperationTaskException if error occurred while scheduling the subscription * @throws ApplicationOperationTaskException if error occurred while scheduling the subscription
*/ */
public void scheduleAppSubscriptionTask(String applicationUUID, List<?> subscribers, public void scheduleAppSubscriptionTask(String applicationUUID, List<?> subscribers,
SubscriptionType subscriptionType, SubAction action, LocalDateTime timestamp) SubscriptionType subscriptionType, SubAction action, long timestamp)
throws ApplicationOperationTaskException { throws ApplicationOperationTaskException {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date(timestamp * 1000));
String space = " "; String space = " ";
String cronExpression = String cronExpression =
String.valueOf(timestamp.getSecond()) + space + timestamp.getMinute() + space + timestamp.getHour() calendar.get(Calendar.SECOND) + space + calendar.get(Calendar.MINUTE) + space
+ space + timestamp.getDayOfMonth() + space + timestamp.getMonth().getDisplayName(TextStyle.SHORT, + calendar.get(Calendar.HOUR_OF_DAY) + space + calendar.get(Calendar.DAY_OF_MONTH) + space
Locale.getDefault()).toUpperCase() + " ? " + timestamp.getYear(); + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault()).toUpperCase() + " ? "
+ calendar.get(Calendar.YEAR);
if (!CronExpression.isValidExpression(cronExpression)) { if (!CronExpression.isValidExpression(cronExpression)) {
String msg = "The cron expression [" + cronExpression + "] generated by the" + " timestamp [" + timestamp String msg = "The cron expression [" + cronExpression + "] generated by the" + " timestamp [" + timestamp
.toString() + "] is invalid"; + "] is invalid";
log.error(msg); log.error(msg);
throw new ApplicationOperationTaskException(msg); throw new ApplicationOperationTaskException(msg);
} }

@ -274,7 +274,7 @@ public class DAOUtil {
} }
subscription.setStatus(ExecutionStatus.valueOf(rs.getString("STATUS"))); subscription.setStatus(ExecutionStatus.valueOf(rs.getString("STATUS")));
subscription.setScheduledAt(rs.getTimestamp("SCHEDULED_AT").toLocalDateTime()); subscription.setScheduledAt(rs.getTimestamp("SCHEDULED_AT").getTime());
subscription.setScheduledBy(rs.getString("SCHEDULED_BY")); subscription.setScheduledBy(rs.getString("SCHEDULED_BY"));
subscription.setDeleted(rs.getBoolean("DELETED")); subscription.setDeleted(rs.getBoolean("DELETED"));
subscriptionDTOS.add(subscription); subscriptionDTOS.add(subscription);

@ -129,7 +129,7 @@ public interface SubscriptionManagementAPI {
name = "timestamp", name = "timestamp",
value = "Timestamp of scheduled install/uninstall operation" value = "Timestamp of scheduled install/uninstall operation"
) )
@QueryParam("timestamp") String timestamp @QueryParam("timestamp") long timestamp
); );
@POST @POST
@ -182,7 +182,7 @@ public interface SubscriptionManagementAPI {
name = "timestamp", name = "timestamp",
value = "Timestamp of scheduled install/uninstall operation" value = "Timestamp of scheduled install/uninstall operation"
) )
@QueryParam("timestamp") String timestamp @QueryParam("timestamp") long timestamp
); );
@POST @POST
@ -229,7 +229,7 @@ public interface SubscriptionManagementAPI {
name = "timestamp", name = "timestamp",
value = "Timestamp of scheduled ent. install operation" value = "Timestamp of scheduled ent. install operation"
) )
@QueryParam("timestamp") String timestamp, @QueryParam("timestamp") long timestamp,
@ApiParam( @ApiParam(
name = "requiresUpdatingExternal", name = "requiresUpdatingExternal",
value = "Should external system such as Google EMM APIs need to be updated." value = "Should external system such as Google EMM APIs need to be updated."
@ -287,7 +287,7 @@ public interface SubscriptionManagementAPI {
name = "timestamp", name = "timestamp",
value = "Timestamp of scheduled ent app install operation" value = "Timestamp of scheduled ent app install operation"
) )
@QueryParam("timestamp") String timestamp, @QueryParam("timestamp") long timestamp,
@ApiParam( @ApiParam(
name = "requiresUpdatingExternal", name = "requiresUpdatingExternal",
value = "Should external system such as Google EMM APIs need to be updated." value = "Should external system such as Google EMM APIs need to be updated."

@ -73,9 +73,9 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@PathParam("uuid") String uuid, @PathParam("uuid") String uuid,
@PathParam("action") String action, @PathParam("action") String action,
@Valid List<DeviceIdentifier> deviceIdentifiers, @Valid List<DeviceIdentifier> deviceIdentifiers,
@QueryParam("timestamp") String timestamp) { @QueryParam("timestamp") long timestamp) {
try { try {
if (StringUtils.isEmpty(timestamp)) { if (0 == timestamp) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
ApplicationInstallResponse response = subscriptionManager ApplicationInstallResponse response = subscriptionManager
.performBulkAppOperation(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), action); .performBulkAppOperation(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), action);
@ -114,9 +114,9 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@PathParam("subType") String subType, @PathParam("subType") String subType,
@PathParam("action") String action, @PathParam("action") String action,
@Valid List<String> subscribers, @Valid List<String> subscribers,
@QueryParam("timestamp") String timestamp) { @QueryParam("timestamp") long timestamp) {
try { try {
if (StringUtils.isEmpty(timestamp)) { if (0 == timestamp) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
ApplicationInstallResponse response = subscriptionManager ApplicationInstallResponse response = subscriptionManager
.performBulkAppOperation(uuid, subscribers, subType, action); .performBulkAppOperation(uuid, subscribers, subType, action);
@ -155,10 +155,10 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@PathParam("uuid") String uuid, @PathParam("uuid") String uuid,
@PathParam("action") String action, @PathParam("action") String action,
@Valid List<DeviceIdentifier> deviceIdentifiers, @Valid List<DeviceIdentifier> deviceIdentifiers,
@QueryParam("timestamp") String timestamp, @QueryParam("timestamp") long timestamp,
@QueryParam("requiresUpdatingExternal") boolean requiresUpdatingExternal) { @QueryParam("requiresUpdatingExternal") boolean requiresUpdatingExternal) {
try { try {
if (StringUtils.isEmpty(timestamp)) { if (0 == timestamp) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
subscriptionManager subscriptionManager
.performEntAppSubscription(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), .performEntAppSubscription(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(),
@ -202,10 +202,10 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@PathParam("subType") String subType, @PathParam("subType") String subType,
@PathParam("action") String action, @PathParam("action") String action,
@Valid List<String> subscribers, @Valid List<String> subscribers,
@QueryParam("timestamp") String timestamp, @QueryParam("timestamp") long timestamp,
@QueryParam("requiresUpdatingExternal") boolean requiresUpdatingExternal) { @QueryParam("requiresUpdatingExternal") boolean requiresUpdatingExternal) {
try { try {
if (StringUtils.isEmpty(timestamp)) { if (0 == timestamp) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
subscriptionManager.performEntAppSubscription(uuid, subscribers, subType, action, requiresUpdatingExternal); subscriptionManager.performEntAppSubscription(uuid, subscribers, subType, action, requiresUpdatingExternal);
String msg = "Application release which has UUID " + uuid + " is installed to subscriber's valid device" String msg = "Application release which has UUID " + uuid + " is installed to subscriber's valid device"
@ -253,11 +253,11 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
* @return {@link Response} of the operation * @return {@link Response} of the operation
*/ */
private Response scheduleApplicationOperationTask(String applicationUUID, List<?> subscribers, private Response scheduleApplicationOperationTask(String applicationUUID, List<?> subscribers,
SubscriptionType subType, SubAction subAction, String timestamp) { SubscriptionType subType, SubAction subAction, long timestamp) {
try { try {
ScheduledAppSubscriptionTaskManager subscriptionTaskManager = new ScheduledAppSubscriptionTaskManager(); ScheduledAppSubscriptionTaskManager subscriptionTaskManager = new ScheduledAppSubscriptionTaskManager();
subscriptionTaskManager.scheduleAppSubscriptionTask(applicationUUID, subscribers, subType, subAction, subscriptionTaskManager.scheduleAppSubscriptionTask(applicationUUID, subscribers, subType, subAction,
LocalDateTime.parse(timestamp, DateTimeFormatter.ISO_LOCAL_DATE_TIME)); timestamp);
} catch (ApplicationOperationTaskException e) { } catch (ApplicationOperationTaskException e) {
String msg = "Error occurred while scheduling the application install operation"; String msg = "Error occurred while scheduling the application install operation";
log.error(msg, e); log.error(msg, e);

@ -61,6 +61,8 @@ public abstract class RandomlyAssignedScheduleTask implements Task {
log.error("Error refreshing Variables necessary for Randomly Assigned Scheduled Task. " + log.error("Error refreshing Variables necessary for Randomly Assigned Scheduled Task. " +
"Dynamic Tasks will not function.", e); "Dynamic Tasks will not function.", e);
} }
} else {
qualifiedToExecuteTask = true;
} }
} }

@ -269,7 +269,7 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION(
APPLICATION_UUID VARCHAR(36) NOT NULL, APPLICATION_UUID VARCHAR(36) NOT NULL,
SUBSCRIBER_LIST LONGVARCHAR NOT NULL, SUBSCRIBER_LIST LONGVARCHAR NOT NULL,
STATUS VARCHAR(15) NOT NULL, STATUS VARCHAR(15) NOT NULL,
SCHEDULED_AT TIMESTAMP NOT NULL, SCHEDULED_AT BIGINT NOT NULL,
SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL,
SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL, SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL,
DELETED BOOLEAN, DELETED BOOLEAN,

@ -270,7 +270,7 @@ CREATE TABLE AP_SCHEDULED_SUBSCRIPTION(
APPLICATION_UUID VARCHAR(200) NOT NULL, APPLICATION_UUID VARCHAR(200) NOT NULL,
SUBSCRIBER_LIST VARCHAR(MAX) NOT NULL, SUBSCRIBER_LIST VARCHAR(MAX) NOT NULL,
STATUS VARCHAR(15) NOT NULL, STATUS VARCHAR(15) NOT NULL,
SCHEDULED_AT DATETIME2(0) NOT NULL, SCHEDULED_AT BIGINT NOT NULL,
SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL,
SCHEDULED_TIMESTAMP DATETIME2(0) NOT NULL, SCHEDULED_TIMESTAMP DATETIME2(0) NOT NULL,
DELETED BIT, DELETED BIT,

@ -269,7 +269,7 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION(
APPLICATION_UUID VARCHAR(36) NOT NULL, APPLICATION_UUID VARCHAR(36) NOT NULL,
SUBSCRIBER_LIST TEXT NOT NULL, SUBSCRIBER_LIST TEXT NOT NULL,
STATUS VARCHAR(15) NOT NULL, STATUS VARCHAR(15) NOT NULL,
SCHEDULED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, SCHEDULED_AT BIGINT NOT NULL,
SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL,
SCHEDULED_TIMESTAMP TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, SCHEDULED_TIMESTAMP TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
DELETED BOOLEAN, DELETED BOOLEAN,

@ -372,7 +372,7 @@ CREATE TABLE AP_SCHEDULED_SUBSCRIPTION (
APPLICATION_UUID VARCHAR(36) NOT NULL, APPLICATION_UUID VARCHAR(36) NOT NULL,
SUBSCRIBER_LIST VARCHAR(4000) NOT NULL, SUBSCRIBER_LIST VARCHAR(4000) NOT NULL,
STATUS VARCHAR(15) NOT NULL, STATUS VARCHAR(15) NOT NULL,
SCHEDULED_AT TIMESTAMP NOT NULL, SCHEDULED_AT NUMBER(19) NOT NULL,
SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL,
SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
DELETED NUMBER(1) NOT_NULL DEFAULT 0, DELETED NUMBER(1) NOT_NULL DEFAULT 0,

@ -299,7 +299,7 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION(
APPLICATION_UUID VARCHAR(36) NOT NULL, APPLICATION_UUID VARCHAR(36) NOT NULL,
SUBSCRIBER_LIST TEXT NOT NULL, SUBSCRIBER_LIST TEXT NOT NULL,
STATUS VARCHAR(15) NOT NULL, STATUS VARCHAR(15) NOT NULL,
SCHEDULED_AT TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP NOT NULL, SCHEDULED_AT BIGINT NOT NULL,
SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL,
SCHEDULED_TIMESTAMP TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP NOT NULL, SCHEDULED_TIMESTAMP TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
DELETED BOOLEAN, DELETED BOOLEAN,

Loading…
Cancel
Save