Skip to content

Commit

Permalink
Publish progress report
Browse files Browse the repository at this point in the history
Initial publish failure handling
  • Loading branch information
jmendeza committed Jan 10, 2025
1 parent 8d41573 commit ad8f1ee
Show file tree
Hide file tree
Showing 39 changed files with 1,673 additions and 578 deletions.
22 changes: 13 additions & 9 deletions src/main/api/studio-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9640,11 +9640,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 +9665,6 @@ components:
example:
siteId: "ed3"
packageId: 17
siteId:
type: string
description: site identifier
example: site123
type:
type: string
description: task type
Expand Down
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
/**
* Interface for content repositories that support git operations
*/
public interface GitContentRepository extends ContentRepository, PublishCapableContentRepository {
public interface GitContentRepository extends ContentRepository {
String PREVIOUS_COMMIT_SUFFIX = "~1";

/**
Expand Down Expand Up @@ -159,6 +159,18 @@ void forAllSitePaths(String siteId,
ThrowingConsumer<String> directoryProcessor,
ThrowingConsumer<String> fileProcessor) throws Exception;

/**
* Execute {@link java.util.function.Consumer<String>} for all file paths in the site
*
* @param siteId site id
* @param fileProcessor the consumer to process the file paths
*/
default void forAllFileSitePaths(String siteId, ThrowingConsumer<String> fileProcessor) throws Exception {
// Ignore directories
forAllSitePaths(siteId, path -> {
}, fileProcessor);
}

/**
* Get the previous commit id from repository for given a site id and a commit id
*
Expand Down Expand Up @@ -321,31 +333,6 @@ boolean createSiteCloneRemote(String siteId, String sandboxBranch, String remote
*/
boolean deleteSite(String siteId);

/**
* Publishes all changes for the given site and target
*
* @param publishPackage the publish package
* @param publishingTarget the publishing target
* @return the change set listing the affected paths and new commit ids (comparing the published repository target branch before and after the publish)
*/
<T extends PublishItemTO> GitPublishChangeSet<T> publishAll(PublishPackage publishPackage,
String publishingTarget,
Collection<T> publishItems) throws ServiceLayerException, IOException;

/**
* Publishes the given items to the given target
*
* @param publishPackage the publish package
* @param publishingTarget the publishing target
* @param publishItems the items to publish
* @param <T> the type of the {@link PublishItemTO} objects
* @return the change set listing the affected paths and new commit id
* @throws ServiceLayerException if there is any error while publishing or publishItems is null or empty
*/
<T extends PublishItemTO> GitPublishChangeSet<T> publish(PublishPackage publishPackage,
String publishingTarget,
Collection<T> publishItems) throws ServiceLayerException, IOException;

/**
* Create copies of the source site's repositories.
* This method will copy sandbox and published (if exists) repositories under a new directory
Expand Down Expand Up @@ -391,33 +378,4 @@ <T extends PublishItemTO> GitPublishChangeSet<T> publish(PublishPackage publishP
*/
String deleteContent(String siteId, Collection<String> paths, String approver) throws ServiceLayerException;

/**
* Store the result of a publish operation
*
* @param successfulItems the paths that were updated
* @param failedItems the paths that failed to publish, mapped to the error message
* @param <T> the actual type of the {@link PublishItemTO} objects
*/
record GitPublishChangeSet<T extends PublishItemTO>(String commitId,
Collection<T> successfulItems,
Collection<T> failedItems) {

/**
* Check if there are successfully published changes
*
* @return true if the package had successful changes and a commit was created, false otherwise
*/
public boolean completed() {
return !ObjectUtils.isEmpty(commitId);
}

/**
* Check if there are failed items
*
* @return true if failed items list contains items, false otherwise
*/
public boolean hasFailedItems() {
return !ObjectUtils.isEmpty(failedItems);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* 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.repository;

import org.craftercms.studio.api.v1.exception.ServiceLayerException;
import org.craftercms.studio.api.v2.dal.publish.PublishPackage;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.Collection;

/**
* Interface for publish operations of a git repository
*/
public interface GitPublishCapableRepository extends GitContentRepository {
/**
* Publishes the given items to the given target
*
* @param publishPackage the publish package
* @param publishingTarget the publishing target
* @param publishItems the items to publish
* @param <T> the type of the {@link PublishItemTO} objects
* @return the change set listing the affected paths and new commit id
* @throws ServiceLayerException if there is any error while publishing or publishItems is null or empty
*/
<T extends PublishItemTO> GitPublishChangeSet<T> publish(PublishPackage publishPackage,
String publishingTarget,
Collection<T> publishItems) throws ServiceLayerException, IOException;

/**
* Publishes all changes for the given site and target
*
* @param publishPackage the publish package
* @param publishingTarget the publishing target
* @return the change set listing the affected paths and new commit ids (comparing the published repository target branch before and after the publish)
*/
<T extends PublishItemTO> GitPublishChangeSet<T> publishAll(PublishPackage publishPackage,
String publishingTarget) throws ServiceLayerException, IOException;

/**
* Execute initial publish for given site
*
* @param publishPackage the package to publish
* @param ignorePaths the paths to ignore
* @param target the target to publish to
* @return commit id of the initial publish.
*/
String initialPublish(PublishPackage publishPackage, Collection<String> ignorePaths,
String target) throws ServiceLayerException;

/**
* Store the result of a publish operation
*
* @param successfulItems the paths that were updated
* @param failedItems the paths that failed to publish, mapped to the error message
* @param <T> the actual type of the {@link PublishItemTO} objects
*/
record GitPublishChangeSet<T extends PublishItemTO>(String commitId,
Collection<T> successfulItems,
Collection<T> failedItems) {

/**
* Check if there are successfully published changes
*
* @return true if the package had successful changes and a commit was created, false otherwise
*/
public boolean completed() {
return !ObjectUtils.isEmpty(commitId);
}

/**
* Check if there are failed items
*
* @return true if failed items list contains items, false otherwise
*/
public boolean hasFailedItems() {
return !ObjectUtils.isEmpty(failedItems);
}
}
}
Loading

0 comments on commit ad8f1ee

Please sign in to comment.