org.codelibs.elasticsearch.taste.river.handler.RecommendationHandler Maven / Gradle / Ivy
package org.codelibs.elasticsearch.taste.river.handler;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import org.codelibs.elasticsearch.taste.exception.TasteException;
import org.codelibs.elasticsearch.taste.model.ElasticsearchDataModel;
import org.codelibs.elasticsearch.taste.model.IndexInfo;
import org.codelibs.elasticsearch.taste.service.TasteService;
import org.codelibs.elasticsearch.util.lang.StringUtils;
import org.codelibs.elasticsearch.util.settings.SettingsUtils;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.river.RiverSettings;
import org.elasticsearch.search.Scroll;
public abstract class RecommendationHandler extends ActionHandler {
protected TasteService tasteService;
public RecommendationHandler(final RiverSettings settings,
final Client client, final TasteService tasteService) {
super(settings, client);
this.tasteService = tasteService;
}
/* (non-Javadoc)
* @see org.codelibs.elasticsearch.taste.river.handler.ActionHandler#execute()
*/
@Override
public abstract void execute();
protected ElasticsearchDataModel createDataModel(final Client client,
final IndexInfo indexInfo,
final Map modelInfoSettings) {
if (StringUtils.isBlank(indexInfo.getUserIndex())) {
throw new TasteException("User Index is blank.");
}
if (StringUtils.isBlank(indexInfo.getPreferenceIndex())) {
throw new TasteException("Preference Index is blank.");
}
if (StringUtils.isBlank(indexInfo.getItemIndex())) {
throw new TasteException("Item Index is blank.");
}
final String className = SettingsUtils
.get(modelInfoSettings, "class",
"org.codelibs.elasticsearch.taste.model.ElasticsearchDataModel");
try {
final Class> clazz = Class.forName(className);
final ElasticsearchDataModel model = (ElasticsearchDataModel) clazz
.newInstance();
model.setClient(client);
model.setPreferenceIndex(indexInfo.getPreferenceIndex());
model.setPreferenceType(indexInfo.getPreferenceType());
model.setUserIndex(indexInfo.getUserIndex());
model.setUserType(indexInfo.getUserType());
model.setItemIndex(indexInfo.getItemIndex());
model.setItemType(indexInfo.getItemType());
model.setUserIdField(indexInfo.getUserIdField());
model.setItemIdField(indexInfo.getItemIdField());
model.setValueField(indexInfo.getValueField());
model.setTimestampField(indexInfo.getTimestampField());
final Map scrollSettings = SettingsUtils.get(
modelInfoSettings, "scroll");
model.setScrollSize(((Number) SettingsUtils.get(scrollSettings,
"size", 1000)).intValue());
model.setScrollKeepAlive(new Scroll(TimeValue
.timeValueSeconds(((Number) SettingsUtils.get(
scrollSettings, "keep_alive", 60L)).longValue())));
final Map querySettings = SettingsUtils.get(
modelInfoSettings, "query");
final String userQuery = SettingsUtils.get(querySettings, "user");
if (StringUtils.isNotBlank(userQuery)) {
model.setUserQueryBuilder(QueryBuilders.queryString(userQuery));
}
final String itemQuery = SettingsUtils.get(querySettings, "item");
if (StringUtils.isNotBlank(itemQuery)) {
model.setUserQueryBuilder(QueryBuilders.queryString(itemQuery));
}
final Map cacheSettings = SettingsUtils.get(
modelInfoSettings, "cache");
final Object weight = SettingsUtils.get(cacheSettings, "weight");
if (weight instanceof Number) {
model.setMaxCacheWeight(((Integer) weight).longValue());
} else {
final long weightSize = parseWeight(weight.toString());
if (weightSize > 0) {
model.setMaxCacheWeight(weightSize);
}
}
return model;
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException e) {
throw new TasteException("Could not create an instance of "
+ className);
}
}
protected void waitFor(final ExecutorService executorService,
final int maxDuration) {
executorService.shutdown();
boolean succeeded = false;
try {
if (maxDuration == 0) {
succeeded = executorService.awaitTermination(Long.MAX_VALUE,
TimeUnit.NANOSECONDS);
} else {
succeeded = executorService.awaitTermination(maxDuration,
TimeUnit.MINUTES);
}
if (!succeeded) {
logger.warn(
"Unable to complete the computation in {} minutes!",
maxDuration);
}
} catch (final InterruptedException e) {
logger.warn("Interrupted a executor.", e);
}
if (!succeeded) {
executorService.shutdownNow();
}
}
private long parseWeight(final String value) {
if (StringUtils.isBlank(value)) {
return 0;
}
try {
final char lastChar = value.charAt(value.length() - 1);
if (lastChar == 'g' || lastChar == 'G') {
return Long.parseLong(value.substring(0, value.length() - 1)) * 1000 * 1000 * 1000;
} else if (lastChar == 'm' || lastChar == 'M') {
return Long.parseLong(value.substring(0, value.length() - 1)) * 1000 * 1000;
} else if (lastChar == 'k' || lastChar == 'K') {
return Long.parseLong(value.substring(0, value.length() - 1)) * 1000;
}
return Long.parseLong(value);
} catch (final Exception e) {
logger.warn("Failed to parse a weight: {}", e, value);
}
return 0;
}
}