Java tutorial
/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.tools.index; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus; import org.elasticsearch.action.admin.indices.status.IndexStatus; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.collect.Maps; import org.joda.time.Period; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.PeriodFormatter; import org.joda.time.format.PeriodFormatterBuilder; import org.springframework.beans.factory.annotation.Autowired; import com.google.common.collect.Lists; import com.enonic.cms.core.content.ContentSpecification; import com.enonic.cms.core.search.ElasticSearchIndexService; import com.enonic.cms.core.search.IndexType; import com.enonic.cms.core.tools.AbstractToolController; import com.enonic.cms.store.dao.ContentDao; public final class IndexMonitorController extends AbstractToolController { protected static final PeriodFormatter HOURS_MINUTES_MILLIS = new PeriodFormatterBuilder().appendHours() .appendSuffix(" h ", " h ").appendMinutes().appendSuffix(" m ", " m ").appendSeconds() .appendSuffix(" s ", " s ").appendMillis().appendSuffix(" ms", " ms").toFormatter(); private static final DateTimeFormatter SIMPLE_DATE_FORMAT = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm"); private static final String GET_ALL_QUERY = "{\n" + " \"from\" : 0,\n" + " \"size\" : 0,\n" + " \"query\" : {\n" + " \"match_all\" : {\n" + " }\n" + " }\n" + "}\n" + ""; public static final String NOT_APPLICABLE = "N/A"; private ElasticSearchIndexService elasticSearchIndexService; private ReindexContentToolService reindexContentToolService; private ContentDao contentDao; @Override protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws Exception { final Map<String, Object> model = Maps.newHashMap(); model.put("baseUrl", getBaseUrl(req)); final String op = req.getParameter("op"); if (!"info".equals(op)) { renderView(req, res, model, "indexMonitorPage"); return; } List<String> errors = Lists.newArrayList(); populateClusterHealth(model, errors); populateReindexInfo(model, errors); final ContentSpecification specification = new ContentSpecification(); specification.setIncludeDeleted(false); final long totalNumberOfContent = contentDao.findCountBySpecification(specification); model.put("totalNumberOfContent", totalNumberOfContent); if (!errors.isEmpty()) { model.put("errors", errors); } renderView(req, res, model, "indexMonitorPage_info"); } private void populateClusterHealth(final Map<String, Object> model, final List<String> errors) { final ClusterHealthResponse clusterHealthResponse = elasticSearchIndexService.getClusterHealth("cms", false); populateInfoFromIndexStatus(model, errors); if (clusterHealthResponse == null) { errors.add("Not able to get clusterHealthResponse"); model.put("activeShards", NOT_APPLICABLE); model.put("clusterStatus", NOT_APPLICABLE); model.put("relocatingShards", NOT_APPLICABLE); model.put("activePrimaryShards", NOT_APPLICABLE); model.put("numberOfNodes", NOT_APPLICABLE); model.put("unassignedShards", NOT_APPLICABLE); model.put("indexExists", NOT_APPLICABLE); model.put("numberOfContent", NOT_APPLICABLE); model.put("numberOfBinaries", NOT_APPLICABLE); } else { model.put("activeShards", clusterHealthResponse.getActiveShards()); final ClusterHealthStatus status = clusterHealthResponse.getStatus(); model.put("clusterStatus", status.toString()); model.put("relocatingShards", clusterHealthResponse.getRelocatingShards()); model.put("activePrimaryShards", clusterHealthResponse.getActivePrimaryShards()); model.put("numberOfNodes", clusterHealthResponse.getNumberOfNodes()); model.put("unassignedShards", clusterHealthResponse.getUnassignedShards()); final List<String> allValidationFailures = clusterHealthResponse.getAllValidationFailures(); if (!allValidationFailures.isEmpty()) { model.put("validationFailures", allValidationFailures); } final boolean indexExists = elasticSearchIndexService.indexExists("cms"); model.put("indexExists", indexExists); model.put("numberOfContent", getTotalHitsContent(status)); model.put("numberOfBinaries", getTotalHitsBinaries(status)); } } private void populateInfoFromIndexStatus(final Map<String, Object> model, final List<String> errors) { final IndexStatus indexStatus = elasticSearchIndexService.getIndexStatus("cms"); if (indexStatus == null) { errors.add("Not able to get indexStatus for index 'cms'"); model.put("numberOfDocuments", NOT_APPLICABLE); model.put("primaryStorageSize", NOT_APPLICABLE); model.put("totalStorageSize", NOT_APPLICABLE); } else { model.put("numberOfDocuments", indexStatus.getDocs().getNumDocs()); model.put("primaryStorageSize", indexStatus.getPrimaryStoreSize()); model.put("totalStorageSize", indexStatus.getStoreSize()); } } private void populateReindexInfo(final Map<String, Object> model, final List<String> errors) { model.put("reindexInProgress", reindexContentToolService.isReIndexInProgress()); model.put("reindexError", reindexContentToolService.isLastReindexFailed()); if (reindexContentToolService.getLastReindexTime() != null) { model.put("lastReindexTime", getLastIndexTimeString()); model.put("lastReindexTimeUsed", getTimeUsedString()); } } private String getLastIndexTimeString() { return SIMPLE_DATE_FORMAT.print(reindexContentToolService.getLastReindexTime()); } private String getTimeUsedString() { final long lastReindexTimeUsed = reindexContentToolService.getLastReindexTimeUsed(); return HOURS_MINUTES_MILLIS.print(new Period(lastReindexTimeUsed)).trim(); } private long getTotalHitsBinaries(final ClusterHealthStatus status) { if (!status.equals(ClusterHealthStatus.RED)) { final SearchResponse response = elasticSearchIndexService.search("cms", IndexType.Binaries.toString(), GET_ALL_QUERY); return response.getHits().getTotalHits(); } else { return -1; } } private long getTotalHitsContent(final ClusterHealthStatus status) { if (!status.equals(ClusterHealthStatus.RED)) { final SearchResponse response = elasticSearchIndexService.search("cms", IndexType.Content.toString(), GET_ALL_QUERY); return response.getHits().getTotalHits(); } else { return -1; } } @Autowired public void setElasticSearchIndexService(ElasticSearchIndexService elasticSearchIndexService) { this.elasticSearchIndexService = elasticSearchIndexService; } @Autowired public void setReindexContentToolService(final ReindexContentToolService reindexContentToolService) { this.reindexContentToolService = reindexContentToolService; } @Autowired public void setContentDao(final ContentDao contentDao) { this.contentDao = contentDao; } }