2016-01-14 5 views
1

Мы создаем веб-скрипт в Alfresco (на основе Java). В определенный интервал этот webscript должен загружать файлы (много файлов) из удаленной системы и обрабатывать их и просматривать файлы в Alfresco.Alfresco - Java-based Webscript - Отправка ответа Асинхронно

Теперь этот веб-скрипт будет запущен из коробки Jenkin, поэтому мы планируем опросить этот статус веб-скрипта, будет ли он завершен или нет, пока весь процесс не завершит процесс. Это будет регулярно повторяться каждый день или неделю.

Как я могу заставить webscript регулярно отправлять промежуточный отклик на работу Jenkin и продолжить процесс. Как только все процессы будут завершены, один и тот же вызов webscript должен отправить завершенный статус в ящик jenkin.

Как я могу это достичь?

Примечание: я не могу использовать Cron. Только можно использовать Jenkin, поскольку вход в webscript будет отправлен от Jenkin (который получен от другого продукта).

+0

Я предлагаю вам посмотреть службы репликации и передачи в Alfresco - у них есть длительные рабочие задания и веб-скрипты, которые позволяют вам проверять статус. Это, вероятно, ваша лучшая модель, чтобы учиться на встроенном в Alfresco – Gagravarr

+0

@Gagravarr, спасибо за ваш вклад. Я посмотрю на них. –

ответ

1

Я не буду спорить с вашим выбором веб-страницы для реализации вашей логики, хотя я не на 100% в порядке с ним.

Что касается вашего вопроса, вы можете сохранить общий статус выполнения вашего задания/логики в некотором одиночном режиме и иметь другой wesbcript (или просто тот же самый с разными параметрами), который возвращает это значение для вас.

3

Ниже я опишу, как реализовать пакетный процесс в Alfresco. Прежде чем вдаваться в подробности, я хотел бы также предложить интегрировать этот процесс с рабочими процессами Activiti (или JBPM, если хотите).

Как описано ниже, процесс отправит события, чтобы уведомить слушателей о ходе работы. Слушатель этих событий может напрямую позвонить Дженкинсу.

Вместо прямого вызова Jenkins слушатель может обновить рабочий процесс. В этом случае логика вызова Jenkins будет реализована в задаче рабочего процесса. Это облегчает разделение логики пакетного процесса с логикой уведомителя. Кроме того, рабочий процесс может также использоваться для хранения информации о ходе работы. Эта информация может быть в конечном итоге опрошена кем-то/кем-то интересным.

Долгий процесс работает:

Я не знаю, какую версию Alfresco вы используете, и я опишу решение для версии 4.1. Alfresco поддерживает пакетную обработку давно работает в основном с классами и интерфейс в пакете org.alfresco.repo.batch:

BatchProcessWorkProvider

BatchProcessor

BatchProcessor.BatchProcessWorker

BatchMonitor

BatchMonitorEvent.java

Вам необходимо обеспечить реализацию для двух интерфейсов: BatchProcessorWorkProvider и BatchProcessor.BatchProcessWorker:

Оба интерфейса прилагаются ниже. Первый возвращает рабочие нагрузки, а второй определяет, что такое рабочий.

BatchProcessor:

/** 
* An interface that provides work loads to the {@link BatchProcessor}. 
* 
* @author Derek Hulley 
* @since 3.4 
*/ 
public interface BatchProcessWorkProvider<T> 
{ 
    /** 
    * Get an estimate of the total number of objects that will be provided by this instance. 
    * Instances can provide accurate answers on each call, but only if the answer can be 
    * provided quickly and efficiently; usually it is enough to to cache the result after 
    * providing an initial estimate. 
    * 
    * @return     a total work size estimate 
    */ 
    int getTotalEstimatedWorkSize(); 

    /** 
    * Get the next lot of work for the batch processor. Implementations should return 
    * the largest number of entries possible; the {@link BatchProcessor} will keep calling 
    * this method until it has enough work for the individual worker threads to process 
    * or until the work load is empty. 
    * 
    * @return     the next set of work object to process or an empty collection 
    *       if there is no more work remaining. 
    */ 
    Collection<T> getNextWork(); 
} 

BatchProcessWorker:

/** 
* An interface for workers to be invoked by the {@link BatchProcessor}. 
*/ 
public interface BatchProcessWorker<T> 
{ 
    /** 
    * Gets an identifier for the given entry (for monitoring/logging purposes). 
    * 
    * @param entry 
    *   the entry 
    * @return the identifier 
    */ 
    public String getIdentifier(T entry); 

    /** 
    * Callback to allow thread initialization before the work entries are 
    * {@link #process(Object) processed}. Typically, this will include authenticating 
    * as a valid user and disbling or enabling any system flags that might affect the 
    * entry processing. 
    */ 
    public void beforeProcess() throws Throwable; 

    /** 
    * Processes the given entry. 
    * 
    * @param entry 
    *   the entry 
    * @throws Throwable 
    *    on any error 
    */ 
    public void process(T entry) throws Throwable; 

    /** 
    * Callback to allow thread cleanup after the work entries have been 
    * {@link #process(Object) processed}. 
    * Typically, this will involve cleanup of authentication and resetting any 
    * system flags previously set. 
    * <p/> 
    * This call is made regardless of the outcome of the entry processing. 
    */ 
    public void afterProcess() throws Throwable; 
} 

На практике BatchProcessWorkProvider возвращает коллекцию "работы, чтобы сделать" (класс "Т"). «Работа над выполнением» - это класс, который вам нужно предоставить. В вашем случае этот класс может предоставить информацию для извлечения подмножества файлов из удаленной системы. Процесс метода будет использовать эту информацию для фактической работы. Как пример, в вашем случае мы можем вызвать T, ImportFiles.

Ваш BatchProcessWorkProvider должен разбить список файлов на коллекцию ImportFiles разумного размера.

«Наиболее важным» метод в BatchProcessWorker является

public void process(ImportFiles filesToImport) throws Throwable; 

Это метод, который вы должны выполнить. Для других методов есть адаптер BatchProcess.BatchProcessWorkerAdapter, который обеспечивает реализацию по умолчанию.

Метод процесса получает в качестве параметра ImportFiles и может использовать его для поиска файлов на удаленных серверах и их импорта.

Наконец, вам нужно создать экземпляр BatchProcessor:

try { 
    final RetryingTransactionHelper retryingTransactionHelper = transactionService.getRetryingTransactionHelper(); 
    BatchProcessor<ImportFiles> batchProcessor = new BatchProcessor<ImportFiles>(processName, 
      retryingTransactionHelper, workProvider, threads, batchSize, 
      applicationEventPublisher, logger, loggingInterval); 
    batchProcessor.process(worker, true); 
} 
catch (LockAcquisitionException e) { 
    /* Manage exception */ 
} 

Где

ProcessName: описание длинного запущенного процесса

workProvider экземпляр BatchProcessWorkProvider

threads: количество рабочих потоков (параллельно)

BATCHSIZE: количество записей для обработки в одной и той же операции

Регистратор: регистратор использовать для отчетности прогресса

loggingInterval: число записей для обработки, прежде чем отчеты о проделанной работе

retryingTransactionHelper : является вспомогательным классом для повторной транзакции, если есть сбой для параллельного обновления (оптимистическая блокировка) или условие взаимоблокировки.

applicationEventPublisher: это экземпляр Spring ApplicationEventPublisher, который обычно (а также для Alfresco) использует SpringContext.

Чтобы отправить события Дженкинсу, вы можете использовать applicationEventPublisher. Следующая ссылка описывает, как ее использовать. Это стандартная функциональность Spring.

Spring events

Событие может быть, например, посланного методом

process(ImportFiles filesToImport) 

описано выше.

Смежные вопросы