/*
* Copyright (c) 2013 Websquared, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v2.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* swsong - initial API and implementation
*/
package org.fastcatsearch.job.indexing;
import java.io.IOException;
import org.fastcatsearch.cluster.Node;
import org.fastcatsearch.cluster.NodeService;
import org.fastcatsearch.common.io.Streamable;
import org.fastcatsearch.db.mapper.IndexingResultMapper.ResultStatus;
import org.fastcatsearch.exception.FastcatSearchException;
import org.fastcatsearch.ir.CollectionIndexBuildIndexer;
import org.fastcatsearch.ir.IRService;
import org.fastcatsearch.ir.analysis.AnalyzerPoolManager;
import org.fastcatsearch.ir.common.IndexingType;
import org.fastcatsearch.ir.config.CollectionContext;
import org.fastcatsearch.ir.config.CollectionIndexStatus.IndexStatus;
import org.fastcatsearch.ir.index.SelectedIndexList;
import org.fastcatsearch.ir.io.DataInput;
import org.fastcatsearch.ir.io.DataOutput;
import org.fastcatsearch.job.Job.JobResult;
import org.fastcatsearch.job.result.IndexingJobResult;
import org.fastcatsearch.job.state.IndexingTaskState;
import org.fastcatsearch.service.ServiceManager;
import org.fastcatsearch.transport.vo.StreamableCollectionContext;
import org.fastcatsearch.transport.vo.StreamableThrowable;
/**
* 전체색인용 색인만 생성한다. 문서는 저장하지 않고, 이미 저장된 문서를 읽어서 색인한다.
*
* index node가 아닌 노드에 전달되면 색인을 수행하지 않는다.
*
* */
public class CollectionIndexBuildFullIndexingJob extends IndexingJob {
private static final long serialVersionUID = -4291415269961866851L;
private CollectionContext collectionContext;
public CollectionIndexBuildFullIndexingJob(){
}
public CollectionIndexBuildFullIndexingJob(CollectionContext collectionContext){
this.collectionContext = collectionContext;
}
@Override
public void requestStop(){
logger.info("Collection [{}] Document Store Job Stop Requested! ", collectionId);
stopRequested = true;
if(indexer != null){
indexer.requestStop();
}
indexingTaskState.addState(IndexingTaskState.STATE_STOP_REQUESTED);
}
@Override
public JobResult doRun() throws FastcatSearchException {
prepare(IndexingType.FULL_INDEX_BUILD, "ALL");
Throwable throwable = null;
ResultStatus resultStatus = ResultStatus.RUNNING;
Object result = null;
long startTime = System.currentTimeMillis();
try {
IRService irService = ServiceManager.getInstance().getService(IRService.class);
AnalyzerPoolManager analyzerPoolManager = irService.createAnalyzerPoolManager(collectionContext.schema().schemaSetting().getAnalyzerSettingList());
//find index node
String indexNodeId = collectionContext.collectionConfig().getIndexNode();
NodeService nodeService = ServiceManager.getInstance().getService(NodeService.class);
Node indexNode = nodeService.getNodeById(indexNodeId);
if(!nodeService.isMyNode(indexNode)){
//Pass job to index node
//작업수행하지 않음.
throw new RuntimeException("Invalid index node collection[" + collectionId + "] node[" + indexNodeId + "]");
}
if(!updateIndexingStatusStart()) {
resultStatus = ResultStatus.CANCEL;
return new JobResult();
}
/*
* Do Document Store!!
*/
//////////////////////////////////////////////////////////////////////////////////////////
SelectedIndexList selectedIndexList = SelectedIndexList.ALL_INDEXING; //TODO 차후 선택적으로 바꾼다.
boolean isIndexed = false;
CollectionIndexBuildIndexer collectionIndexBuildIndexer = new CollectionIndexBuildIndexer(collectionContext, analyzerPoolManager, selectedIndexList);
indexer = collectionIndexBuildIndexer;
collectionIndexBuildIndexer.setTaskState(indexingTaskState);
try {
indexer.doIndexing();
} finally {
if (indexer != null) {
isIndexed = indexer.close();
}
}
if(!isIndexed && stopRequested){
//여기서 끝낸다.
throw new IndexingStopException();
}
int duration = (int) (System.currentTimeMillis() - startTime);
IndexStatus indexStatus = collectionContext.indexStatus().getFullIndexStatus();
indexingLogger.info("[{}] Collection Index Build Full Indexing Finished! {} time = {}", collectionId, indexStatus, duration);
result = new IndexingJobResult(collectionId, indexStatus, duration);
resultStatus = ResultStatus.SUCCESS;
return new JobResult(result);
} catch (IndexingStopException e){
if(stopRequested){
resultStatus = ResultStatus.STOP;
}else{
resultStatus = ResultStatus.CANCEL;
}
result = new IndexingJobResult(collectionId, null, (int) (System.currentTimeMillis() - startTime), false);
return new JobResult(result);
} catch (Throwable e) {
indexingLogger.error("[" + collectionId + "] Indexing", e);
throwable = e;
resultStatus = ResultStatus.FAIL;
throw new FastcatSearchException("ERR-00500", throwable, collectionId); // 전체색인실패.
} finally {
Streamable streamableResult = null;
if (throwable != null) {
streamableResult = new StreamableThrowable(throwable);
} else if (result instanceof Streamable) {
streamableResult = (Streamable) result;
}
updateIndexingStatusFinish(resultStatus, streamableResult);
}
}
@Override
public void readFrom(DataInput input) throws IOException {
super.readFrom(input);
StreamableCollectionContext streamableCollectionContext = new StreamableCollectionContext(environment);
streamableCollectionContext.readFrom(input);
this.collectionContext = streamableCollectionContext.collectionContext();
}
@Override
public void writeTo(DataOutput output) throws IOException {
super.writeTo(output);
StreamableCollectionContext streamableCollectionContext = new StreamableCollectionContext(collectionContext);
streamableCollectionContext.writeTo(output);
}
}