com.bagri.server.hazelcast.management.DocumentManagement Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bagri-server-hazelcast Show documentation
Show all versions of bagri-server-hazelcast Show documentation
Bagri DB Cache: Hazelcast implementation
The newest version!
package com.bagri.server.hazelcast.management;
import static com.bagri.core.Constants.pn_document_headers;
import static com.bagri.support.util.PropUtils.propsFromString;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedOperationParameter;
import org.springframework.jmx.export.annotation.ManagedOperationParameters;
import org.springframework.jmx.export.annotation.ManagedResource;
import com.bagri.core.api.BagriException;
import com.bagri.core.api.DocumentAccessor;
import com.bagri.core.system.Collection;
import com.bagri.core.system.Schema;
import com.bagri.server.hazelcast.task.doc.DocumentStructureProvider;
import com.bagri.server.hazelcast.task.schema.SchemaDocCleaner;
import com.bagri.server.hazelcast.task.stats.StatisticSeriesCollector;
import com.bagri.server.hazelcast.task.stats.StatisticTotalsCollector;
import com.bagri.server.hazelcast.task.stats.StatisticsReseter;
import com.bagri.support.stats.StatsAggregator;
import com.bagri.support.util.FileUtils;
import com.bagri.support.util.JMXUtils;
import com.hazelcast.core.Member;
import com.hazelcast.core.Partition;
@ManagedResource(description="Schema Documents Management MBean")
public class DocumentManagement extends SchemaFeatureManagement {
private CompositeData docTotals = null;
private com.bagri.core.api.DocumentManagement docManager;
public DocumentManagement(String schemaName) {
super(schemaName);
}
@Override
protected String getFeatureKind() {
return "DocumentManagement";
}
@Override
public void setSchemaManager(SchemaManager schemaManager) {
super.setSchemaManager(schemaManager);
this.docManager = schemaManager.getRepository().getDocumentManagement();
}
private void initAggregator() {
if (aggregator == null) {
aggregator = new StatsAggregator() {
@Override
public Object[] aggregateStats(Object[] source, Object[] target) {
target[2] = source[2]; // collection
target[3] = (Long) source[3] + (Long) target[3]; // size
target[4] = (Integer) source[4] + (Integer) target[4]; // number of docs
target[5] = (Integer) source[5] + (Integer) target[5]; // number of elts
target[6] = (Integer) source[6] + (Integer) target[6]; // number of fragments
double size = (Long) target[3];
target[0] = size/(Integer) target[4]; // avg in bytes
size = (Integer) target[5];
target[1] = size/(Integer) target[4]; // avg in elts
return target;
}
};
}
}
@ManagedOperation(description="delete all Schema documents")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "evictOnly", description = "Delete from Cache or from Cache and CacheStore too")})
public boolean clear(boolean evictOnly) {
SchemaDocCleaner task = new SchemaDocCleaner(schemaName, evictOnly);
Map> results = execService.submitToAllMembers(task);
boolean result = true;
for (Map.Entry> entry: results.entrySet()) {
try {
if (!entry.getValue().get()) {
result = false;
}
} catch (InterruptedException | ExecutionException ex) {
logger.error("clear.error; ", ex);
//throw new RuntimeException(ex.getMessage());
}
}
return result;
}
@ManagedAttribute(description="Returns Schema Totals")
public CompositeData getTotalCounts() {
collectTotals();
return docTotals;
}
private void collectTotals() {
initAggregator();
docTotals = super.getTotalsStatistics(new StatisticTotalsCollector(schemaName, "docStats"), aggregator);
}
@ManagedAttribute(description="Returns Schema size in documents")
public Integer getDocumentCount() {
collectTotals();
return (Integer) docTotals.get("Number of documents");
}
@ManagedAttribute(description="Returns Schema size in elements")
public Integer getElementCount() {
if (docTotals == null) {
collectTotals();
}
return (Integer) docTotals.get("Number of elements");
}
@ManagedAttribute(description="Returns Schema size in bytes")
public Long getSchemaSize() {
if (docTotals == null) {
collectTotals();
}
return (Long) docTotals.get("Consumed size");
}
@ManagedOperation(description="Return Document Elements")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "uri", description = "Document identifier")})
public CompositeData getDocumentElements(String uri) {
//
//docManager.
DocumentStructureProvider task = new DocumentStructureProvider(null, uri);
Future result = execService.submitToKeyOwner(task, uri);
try {
return result.get();
} catch (InterruptedException | ExecutionException ex) {
logger.error("getDocumentElements.error; ", ex);
throw new RuntimeException(ex.getMessage());
}
}
@ManagedOperation(description="Return Document Fields")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "uri", description = "Document identifier")})
public CompositeData getDocumentInfo(String uri) {
try {
Properties props = new Properties();
props.setProperty("bdb.document.headers", String.valueOf(DocumentAccessor.HDR_DOCUMENT_INFO));
DocumentAccessor doc = docManager.getDocument(uri, props);
CompositeData result = null;
if (doc != null) {
Map docInfo = new HashMap<>(11);
docInfo.put("key", doc.getDocumentKey());
docInfo.put("version", doc.getVersion());
docInfo.put("uri", doc.getUri());
docInfo.put("size", doc.getSizeInBytes());
docInfo.put("encoding", doc.getEncoding());
docInfo.put("created at", new Date(doc.getCreateadAt()));
docInfo.put("created by", doc.getCreatedBy());
docInfo.put("start tx", doc.getTxStart());
docInfo.put("elements", doc.getSizeInElements());
docInfo.put("fragments", doc.getSizeInFragments());
docInfo.put("collections", doc.getCollections());
docInfo.put("content type", doc.getContentType());
result = JMXUtils.mapToComposite("document", "Document Info", docInfo);
}
logger.debug("getDocumentInfo; returning: {}", result);
return result;
} catch (BagriException ex) {
logger.error("getDocumentInfo.error: {}", ex.getMessage(), ex);
throw new RuntimeException(ex.getMessage());
}
}
@ManagedOperation(description="Return Document Location Info")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "uri", description = "Document identifier")})
public CompositeData getDocumentLocation(String uri) {
try {
Properties props = new Properties();
props.setProperty("bdb.document.headers", String.valueOf(DocumentAccessor.HDR_URI));
DocumentAccessor doc = docManager.getDocument(uri, props);
CompositeData result = null;
if (doc != null) {
Partition part = hzClient.getPartitionService().getPartition(doc.getUri().hashCode());
Map location = new HashMap<>(2);
location.put("partition", part.getPartitionId());
location.put("owner", part.getOwner().toString());
result = JMXUtils.mapToComposite("document", "Document Location", location);
}
logger.debug("getDocumentLocation; returning: {}", result);
return result;
} catch (BagriException ex) {
logger.error("getDocumentLocation.error: {}", ex.getMessage(), ex);
throw new RuntimeException(ex.getMessage());
}
}
@ManagedOperation(description="Return Document Content")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "uri", description = "Document identifier"),
@ManagedOperationParameter(name = "properties", description = "A list of properties in key=value form separated by semicolon")})
public String getDocumentContent(String uri, String properties) {
try {
String result = null;
DocumentAccessor doc = docManager.getDocument(uri, propsFromString(properties));
if (doc != null) {
result = doc.getContent();
}
logger.debug("getDocumentContent; got accessor {} for uri: {}, props: {}; returning: {}", doc, uri, properties, result);
return result;
} catch (IOException | BagriException ex) {
logger.error("getDocumentContent.error: {}", ex.getMessage(), ex);
throw new RuntimeException(ex.getMessage());
} catch (Throwable ex) {
logger.error("getDocumentContent.error: {}", ex.getMessage(), ex);
throw new RuntimeException(ex.getMessage());
}
}
@ManagedOperation(description="Register Document")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "docFile", description = "A full path to XML file to register"),
@ManagedOperationParameter(name = "properties", description = "A list of properties in key=value form separated by semicolon")})
public String registerDocument(String docFile, String properties) {
String uri = Paths.get(docFile).getFileName().toString();
try {
String xml = FileUtils.readTextFile(docFile);
DocumentAccessor doc = docManager.storeDocument(uri, xml, propsFromString(properties));
return doc.getUri();
} catch (IOException | BagriException ex) {
logger.error("registerDocument.error: {}", ex.getMessage(), ex);
throw new RuntimeException(ex.getMessage());
}
}
@ManagedOperation(description="Updates already registerd Document")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "uri", description = "A new uri for the file or null"),
@ManagedOperationParameter(name = "docFile", description = "A full path to XML file to register"),
@ManagedOperationParameter(name = "properties", description = "A list of properties in key=value form separated by semicolon")})
public String updateDocument(String uri, String docFile, String properties) {
try {
String content = FileUtils.readTextFile(docFile);
DocumentAccessor doc = docManager.storeDocument(uri, content, propsFromString(properties));
return doc.getUri();
} catch (IOException | BagriException ex) {
logger.error("updateDocument.error: {}", ex.getMessage(), ex);
throw new RuntimeException(ex.getMessage());
}
}
@ManagedOperation(description="Remove Document")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "uri", description = "Document identifier"),
@ManagedOperationParameter(name = "properties", description = "A list of properties in key=value form separated by semicolon")})
public boolean removeDocument(String uri, String properties) {
try {
docManager.removeDocument(uri, propsFromString(properties));
return true;
} catch (Exception ex) {
logger.error("removeDocument.error: {}", ex.getMessage(), ex);
throw new RuntimeException(ex.getMessage());
}
}
private int processFilesInCatalog(Path catalog, String properties) {
int result = 0;
String docType = schemaManager.getDataFormat();
logger.debug("processFilesInCatalog; got docType: {}", docType);
try (DirectoryStream stream = Files.newDirectoryStream(catalog, "*." + docType.toLowerCase())) {
for (Path path: stream) {
if (Files.isDirectory(path)) {
result += processFilesInCatalog(path, properties);
} else {
registerDocument(path.toString(), properties);
result++;
}
}
return result;
} catch (IOException ex) {
logger.error("processFilesInCatalog.error: {}", ex.getMessage(), ex);
throw new RuntimeException(ex.getMessage());
}
}
@ManagedOperation(description="Register Documents")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "path", description = "A full path to directory containing XML files to register"),
@ManagedOperationParameter(name = "properties", description = "A list of properties in key=value form separated by semicolon")})
public int registerDocuments(String path, String properties) {
Path catalog = Paths.get(path);
return processFilesInCatalog(catalog, properties);
}
@Override
protected java.util.Collection getSchemaFeatures(Schema schema) {
return schema.getCollections();
}
@ManagedAttribute(description="Return Collections registered in the Schema")
public TabularData getCollections() {
return getTabularFeatures("collection", "Collection definition", "name");
}
@ManagedOperation(description="Creates a new Collection")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "name", description = "Collection name to create"),
@ManagedOperationParameter(name = "docType", description = "Root path for document type, if needed"),
@ManagedOperationParameter(name = "description", description = "Collection description")})
public void addCollection(String name, String docType, String description) {
logger.trace("addCollection.enter;");
long stamp = System.currentTimeMillis();
Collection collect = schemaManager.addCollection(name, docType, description);
if (collect == null) {
throw new IllegalStateException("Collection '" + name + "' in schema '" + schemaName + "' already exists");
}
int cnt = 0;
stamp = System.currentTimeMillis() - stamp;
logger.trace("addCollection.exit; collection added on {} members; timeTaken: {}", cnt, stamp);
}
@ManagedOperation(description="Removes an existing Collection")
@ManagedOperationParameters({@ManagedOperationParameter(name = "name", description = "Collection name to remove")})
public void removeCollection(String name) {
logger.trace("removeCollection.enter;");
long stamp = System.currentTimeMillis();
if (!schemaManager.deleteCollection(name)) {
throw new IllegalStateException("Collection '" + name + "' in schema '" + schemaName + "' does not exist");
}
int cnt = 0;
stamp = System.currentTimeMillis() - stamp;
logger.trace("removeCollection.exit; collection deleted on {} members; timeTaken: {}", cnt, stamp);
}
@ManagedOperation(description="Enables/Disables an existing Collection")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "name", description = "Collection name to enable/disable"),
@ManagedOperationParameter(name = "enable", description = "enable/disable collection")})
public void enableCollection(String name, boolean enable) {
if (!schemaManager.enableCollection(name, enable)) {
throw new IllegalStateException("Collection '" + name + "' in schema '" + schemaName +
"' does not exist or already " + (enable ? "enabled" : "disabled"));
}
}
@ManagedAttribute(description="Returns aggregated DocumentManagement invocation statistics, per method")
public TabularData getCollectionStatistics() {
initAggregator();
return super.getSeriesStatistics(new StatisticSeriesCollector(schemaName, "docStats"), aggregator);
}
@ManagedOperation(description="Reset DocumentManagement invocation statistics")
public void resetStatistics() {
super.resetStatistics(new StatisticsReseter(schemaName, "docStats"));
}
@ManagedOperation(description="Add Document to Collection")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "uri", description = "Document identifier"),
@ManagedOperationParameter(name = "clnName", description = "Collection name")})
public int addDocumentToCollection(String uri, String clnName) {
Collection cln = this.schemaManager.getEntity().getCollection(clnName);
if (cln != null) {
return docManager.addDocumentToCollections(uri, new String[] {clnName});
}
logger.info("addDocumentToCollection; no collection found for name: {}", clnName);
return 0;
}
@ManagedOperation(description="Remove Document from Collection")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "uri", description = "Document identifier"),
@ManagedOperationParameter(name = "clnName", description = "Collection name")})
public int removeDocumentFromCollection(String uri, String clnName) {
Collection cln = schemaManager.getEntity().getCollection(clnName);
if (cln != null) {
return docManager.removeDocumentFromCollections(uri, new String[] {clnName});
}
logger.info("removeDocumentFromCollection; no collection found for name: {}", clnName);
return 0;
}
@ManagedOperation(description="Return Documents which belongs to Collection")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "clName", description = "Collection name"),
@ManagedOperationParameter(name = "properties", description = "A list of properties in key=value form separated by semicolon")})
public java.util.Collection getCollectionDocuments(String clName, String properties) {
if (clName != null && !"All Documents".equals(clName)) {
Collection cln = schemaManager.getEntity().getCollection(clName);
if (cln == null) {
logger.info("getCollectionDocuments; got unknown collection: {}", clName);
return null;
}
}
try {
return getUris("collections.contains(" + clName + "), txFinish = 0", properties);
} catch (Exception ex) {
logger.error("getCollectionDocuments.error", ex);
return null;
}
}
@ManagedOperation(description="Return Documents matching the pattern provided")
@ManagedOperationParameters({
@ManagedOperationParameter(name = "pattern", description = "A pattern to match documents, like: createdBy = admin, bytes > 100"),
@ManagedOperationParameter(name = "properties", description = "A list of properties in key=value form separated by semicolon")})
public java.util.Collection getDocumentUris(String pattern, String properties) {
try {
return getUris(pattern, properties);
} catch (Exception ex) {
logger.error("getDocumentUris.error", ex);
return null;
}
}
private java.util.Collection getUris(String pattern, String properties) throws Exception {
Properties props = propsFromString(properties);
if (props == null) {
props = new Properties();
}
props.setProperty(pn_document_headers, String.valueOf(DocumentAccessor.HDR_URI));
Iterable uris = (Iterable) docManager.getDocuments(pattern, props);
List result = new ArrayList<>(); //uris.size()
for (DocumentAccessor doc: uris) {
result.add(doc.getUri());
}
//uris.close();
logger.debug("getUris; returning {} uris", result);
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy