Skip to content

Commit

Permalink
Publish progress report (#3686)
Browse files Browse the repository at this point in the history
* Publish progress report
Initial publish failure handling

* TaskManagerImpl tests

* Publisher unit tests

* TaskManager: split tasks into site and global tasks. Publish status API to get the current task progress. Publish status API spec update
  • Loading branch information
jmendeza authored Jan 17, 2025
1 parent f2ebaf0 commit 58c083e
Show file tree
Hide file tree
Showing 45 changed files with 2,024 additions and 726 deletions.
56 changes: 15 additions & 41 deletions src/main/api/studio-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6866,8 +6866,6 @@ paths:
$ref: '#/components/schemas/ApiResponse'
publishingStatus:
$ref: '#/components/schemas/PublishingStatus'
progress:
$ref: '#/components/schemas/PublishTaskProgress'
'400':
$ref: '#/components/responses/BadRequest'
'401':
Expand Down Expand Up @@ -9640,11 +9638,19 @@ components:
allOf:
- type: object
properties:
packageId:
type: integer
format: int64
description: package identifier
example: 123
result:
description: result of the publish task execution
type: object
properties:
success:
type: boolean
description: true if task was successful, otherwise false
message:
type: string
description: message of the task execution
result:
type: integer
description: final state of the publish package
- $ref: '#/components/schemas/AbstractTaskProgress'

AbstractTaskProgress:
Expand All @@ -9657,10 +9663,6 @@ components:
example:
siteId: "ed3"
packageId: 17
siteId:
type: string
description: site identifier
example: site123
type:
type: string
description: task type
Expand Down Expand Up @@ -9787,39 +9789,11 @@ components:
enabled:
type: boolean
description: true if publishing for site is enabled, otherwise false
status:
type: string
description: publishing status for site
lockOwner:
type: string
description: studio instance owner of publishing lock
lockTTL:
type: string
description: TTL timestamp for publishing lock
totalItems:
type: integer
format: int32
description: total number of item being published right now
numberOfItems:
type: integer
format: int32
description: number of items published so far
submissionId:
type: string
description: identifier of a submission being published
publishingTarget:
type: string
description: publishing target for package
published:
type: boolean
description: true if site has been published at least once (initial publish; published repository exist), otherwise false

required:
- enabled
- status
- message
- lockOwner
- lockTTL
currentTask:
$ref: '#/components/schemas/PublishTaskProgress'

DeploymentHistoryGroup:
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.craftercms.studio.api.v1.dal;

import org.apache.ibatis.annotations.Param;
import org.craftercms.studio.api.v2.dal.PublishStatus;

import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -85,13 +84,6 @@ public interface SiteFeedMapper {

String getSiteState(@Param(SITE_ID) String siteId);

/**
* Get publishing status for site
* @param siteId site identifier
* @return Publishing status
*/
PublishStatus getPublishingStatus(@Param(SITE_ID) String siteId);

/**
* Duplicate a site in the database.
* Notice that populateItemParentId SP should be called after this method to populate the new site's item parent ids.
Expand Down
95 changes: 14 additions & 81 deletions src/main/java/org/craftercms/studio/api/v2/dal/PublishStatus.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
* Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published by
Expand All @@ -16,100 +16,25 @@

package org.craftercms.studio.api.v2.dal;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.craftercms.studio.api.v2.task.TaskProgress;
import org.craftercms.studio.model.task.PublishTask;

public class PublishStatus {

// TODO: remove this and publishing_status column when implementing the
// UM for the publisher refactor
public static final String READY = "ready";
public static final String READY_WITH_ERRORS = "readyWithErrors";
public static final String QUEUED = "queued";
public static final String PROCESSING = "processing";
public static final String PUBLISHING = "publishing";
public static final String STOPPED = "stopped";
public static final String ERROR = "error";

@JsonIgnore
private long id;
private boolean enabled;
@JsonIgnore
private int enabledAsInt;
private String status;

private String publishingTarget;
private String submissionId;
private int numberOfItems;
private int totalItems;

private boolean published;

@JsonIgnore
public long getId() {
return id;
}

@JsonIgnore
public void setId(long id) {
this.id = id;
}
private TaskProgress<PublishTask.PublishTaskId, Long> currentTask;

public boolean isEnabled() {
return enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
this.enabledAsInt = this.enabled? 1 : 0;
}

@JsonIgnore
public int getEnabledAsInt() {
return enabledAsInt;
}

@JsonIgnore
public void setEnabledAsInt(int enabledAsInt) {
this.enabledAsInt = enabledAsInt;
this.enabled = enabledAsInt > 0;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public String getPublishingTarget() {
return publishingTarget;
}

public void setPublishingTarget(String publishingTarget) {
this.publishingTarget = publishingTarget;
}

public String getSubmissionId() {
return submissionId;
}

public void setSubmissionId(String submissionId) {
this.submissionId = submissionId;
}

public int getNumberOfItems() {
return numberOfItems;
}

public void setNumberOfItems(int numberOfItems) {
this.numberOfItems = numberOfItems;
}

public int getTotalItems() {
return totalItems;
}

public void setTotalItems(int totalItems) {
this.totalItems = totalItems;
}

public boolean isPublished() {
Expand All @@ -119,4 +44,12 @@ public boolean isPublished() {
public void setPublished(boolean published) {
this.published = published;
}

public void setCurrentTask(final TaskProgress<PublishTask.PublishTaskId, Long> currentTask) {
this.currentTask = currentTask;
}

public TaskProgress<PublishTask.PublishTaskId, Long> getCurrentTask() {
return currentTask;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ public interface ItemTargetDAO {
String TARGET = "target";
String LIVE_TARGET = "liveTarget";
String STAGING_TARGET = "stagingTarget";
String TARGETS = "targets";
String TIMESTAMP = "timestamp";
String PATHS = "paths";
String ITEM_FAILURE_STATE = "itemFailureState";

/**
* Update for successful publish items in the package.
Expand Down Expand Up @@ -93,13 +93,17 @@ void updateForCompletePackage(@Param(PACKAGE_ID) long packageId,
/**
* Populate the item_target table for the initial publish.
*
* @param siteId the site id
* @param targets the publishing targets
* @param commitId the commit id of published repository
* @param timestamp the timestamp for the published_on date
* @param siteId the site id
* @param packageId the package id
* @param itemFailureState the state to match failed items for the target
* @param target the publishing target
* @param commitId the commit id of published repository
* @param timestamp the timestamp for the published_on date
*/
void insertForInitialPublish(@Param(SITE_ID) long siteId,
@Param(TARGETS) Collection<String> targets,
@Param(PACKAGE_ID) long packageId,
@Param(ITEM_FAILURE_STATE) long itemFailureState,
@Param(TARGET) String target,
@Param(COMMIT_ID) String commitId,
@Param(TIMESTAMP) Instant timestamp);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public interface PublishDAO {
String SITE_STATES = "siteStates";
String ERROR = "error";
String ITEM_SUCCESS_STATE = "itemSuccessState";
String ITEM_FAILURE_STATE = "itemFailureState";
String ITEM_PUBLISHED_STATE = "publishState";
String ON_STATES_BIT_MAP = "onStatesBitMap";
String OFF_STATES_BIT_MAP = "offStatesBitMap";
Expand Down Expand Up @@ -147,6 +148,32 @@ void updateItemStateBits(@Param(PACKAGE_ID) long packageId,
*/
void insertPackage(@Param(PUBLISH_PACKAGE) PublishPackage publishPackage, @Param(PACKAGE_READY_STATE) long packageState);

/**
* Insert the failed initial publish items into the publish_item table
*
* @param packageId the package id
* @param publishItems the failed items
*/
void insertInitialPublishItems(@Param(PACKAGE_ID) long packageId,
@Param(ITEMS) Collection<PublishItem> publishItems);

/**
* Update the site item states after the initial publish
*
* @param siteId the site id
* @param packageId the package id
* @param itemFailureState the state to match the failed items for the target
* @param successOnMask the states to flip on for successful items
* @param successOffMask the states to flip off for successful items
* @param failureOffMask the states to flip off for failed items
*/
void updateItemStatesForInitialPublish(@Param(SITE_ID) long siteId,
@Param(PACKAGE_ID) long packageId,
@Param(ITEM_FAILURE_STATE) long itemFailureState,
@Param(SUCCESS_ON_BIT_MAP) long successOnMask,
@Param(SUCCESS_OFF_BIT_MAP) long successOffMask,
@Param(FAILURE_OFF_BIT_MAP) long failureOffMask);

/**
* Insert items into a publish package
*
Expand Down Expand Up @@ -411,7 +438,7 @@ int getMatchingPublishItemCount(@Param(SITE_ID) String siteId, @Param(PACKAGE_ID
* @param onStatesBitMap the state bits to set to on
* @param offStatesBitMap the state bits to set to off
*/
void updatePublishItemState(@Param(PACKAGE_ID) long id,
void updatePublishItemsState(@Param(PACKAGE_ID) long id,
@Param(ON_STATES_BIT_MAP) long onStatesBitMap,
@Param(OFF_STATES_BIT_MAP) long offStatesBitMap);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void setPackageState(long packageState) {
this.packageState = packageState;
}

public void setPackageState(final long onBits, final long offBits) {
public void updatePackageState(final long onBits, final long offBits) {
this.packageState = (this.packageState | onBits) & ~offBits;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2007-2024 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.craftercms.studio.api.v2.event.task;

import org.craftercms.studio.api.v2.event.BroadcastEvent;
import org.craftercms.studio.api.v2.event.StudioEvent;
import org.craftercms.studio.api.v2.task.TaskProgress;

/**
* Event triggered when a task is state changes
*/
public class TaskEvent extends StudioEvent implements BroadcastEvent {
public static final String EVENT_TYPE_TASK_COMPLETED = "TASK_COMPLETED";
public static final String EVENT_TYPE_TASK_STARTED = "TASK_STARTED";
public static final String EVENT_TYPE_TASK_PROGRESS = "TASK_PROGRESS";

private final TaskProgress<?, ?> progress;
private final String eventType;

public TaskEvent(final TaskProgress<?, ?> progress, final String eventType) {
this.progress = progress;
this.eventType = eventType;
}

/**
* Get the {@link TaskProgress} associated with this event
*
* @return the task progress
*/
public TaskProgress<?, ?> getProgress() {
return progress;
}

@Override
public String getEventType() {
return eventType;
}

@Override
public String toString() {
return """
TaskEvent {taskId=%s, timestamp=%s, eventType=%s, progress=%s}
""".formatted(progress.getTask().getTaskId(),
timestamp,
getEventType(),
progress);
}
}
Loading

0 comments on commit 58c083e

Please sign in to comment.