/* * Copyright 2013 Eediom Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.araqne.logdb.metadata; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.felix.ipojo.annotations.Component; import org.apache.felix.ipojo.annotations.Invalidate; import org.apache.felix.ipojo.annotations.Requires; import org.apache.felix.ipojo.annotations.Validate; import org.araqne.log.api.FieldDefinition; import org.araqne.logdb.AccountService; import org.araqne.logdb.FieldOrdering; import org.araqne.logdb.FunctionRegistry; import org.araqne.logdb.MetadataCallback; import org.araqne.logdb.MetadataProvider; import org.araqne.logdb.MetadataService; import org.araqne.logdb.Permission; import org.araqne.logdb.Privilege; import org.araqne.logdb.QueryContext; import org.araqne.logdb.Row; import org.araqne.logdb.SecurityGroup; import org.araqne.logdb.query.parser.CommandOptions; import org.araqne.logdb.query.parser.ParseResult; import org.araqne.logdb.query.parser.QueryTokenizer; import org.araqne.logstorage.LockKey; import org.araqne.logstorage.LockStatus; import org.araqne.logstorage.LogFileService; import org.araqne.logstorage.LogFileServiceRegistry; import org.araqne.logstorage.LogRetentionPolicy; import org.araqne.logstorage.LogStorage; import org.araqne.logstorage.LogTableRegistry; import org.araqne.logstorage.StorageConfig; import org.araqne.logstorage.TableConfig; import org.araqne.logstorage.TableSchema; import org.araqne.storage.api.FilePath; @Component(name = "logdb-table-metadata") public class TableMetadataProvider implements MetadataProvider, FieldOrdering { @Requires private LogTableRegistry tableRegistry; @Requires private AccountService accountService; @Requires private LogFileServiceRegistry lfsRegistry; @Requires private LogStorage storage; @Requires private MetadataService metadataService; @Requires private FunctionRegistry functionRegistry; @Validate public void start() { metadataService.addProvider(this); } @Invalidate public void stop() { if (metadataService != null) metadataService.removeProvider(this); } @Override public String getType() { return "tables"; } @Override public void verify(QueryContext context, String queryString) { QueryTokenizer.parseOptions(context, queryString, 0, Arrays.asList("verbose"), functionRegistry); } @SuppressWarnings("unchecked") @Override public void query(QueryContext context, String queryString, MetadataCallback callback) { ParseResult r = QueryTokenizer.parseOptions(context, queryString, 0, Arrays.asList("verbose"), functionRegistry); Map<String, String> options = (Map<String, String>) r.value; boolean verbose = CommandOptions.parseBoolean(options.get("verbose")); int next = r.next; queryString = queryString.substring(next).trim(); List<String> targetTables = MetadataQueryStringParser.getFilteredTableNames(context.getSession(), tableRegistry, accountService, queryString); for (String tableName : tableRegistry.getTableNames()) { if (targetTables.contains(tableName)) if (accountService.checkPermission(context.getSession(), tableName, Permission.READ)) writeTableInfo(context, tableName, verbose, callback); } } private void writeTableInfo(QueryContext context, String tableName, boolean verbose, MetadataCallback callback) { Map<String, Object> m = new HashMap<String, Object>(); m.put("table", tableName); TableSchema s = tableRegistry.getTableSchema(tableName); StorageConfig primaryStorage = s.getPrimaryStorage(); LogFileService lfs = lfsRegistry.getLogFileService(primaryStorage.getType()); // primary storage m.put("primary_configs", marshal(lfs, s.getPrimaryStorage())); // replica storage m.put("replica_configs", marshal(lfs, s.getReplicaStorage())); // field definitions List<FieldDefinition> fields = s.getFieldDefinitions(); if (fields != null) { for (FieldDefinition field : fields) { String line = null; if (field.getLength() > 0) line = field.getName() + "\t" + field.getType() + "(" + field.getLength() + ")"; line = field.getName() + "\t" + field.getType(); m.put("fields", line); } } m.put("metadata", s.getMetadata()); // retention pollicy LogRetentionPolicy retentionPolicy = storage.getRetentionPolicy(tableName); String retention = null; if (retentionPolicy != null && retentionPolicy.getRetentionDays() > 0) retention = retentionPolicy.getRetentionDays() + "days"; m.put("retention_policy", retention); m.put("data_path", storage.getTableDirectory(tableName).getAbsolutePath()); LockStatus status = storage.lockStatus(new LockKey("script", tableName, null)); m.put("is_locked", status.isLocked()); if (status.isLocked()) { m.put("lock_owner", status.getOwner()); m.put("lock_purpose", status.getPurposes().toArray(new String[0])); m.put("lock_reentcnt", status.getReentrantCount()); } else { m.put("lock_owner", null); m.put("lock_purpose", null); m.put("lock_reentcnt", null); } List<Object> privileges = new ArrayList<Object>(); for (Privilege p : accountService.getPrivileges(context.getSession(), null)) { if (!p.getTableName().equals(tableName)) continue; Map<String, Object> privilege = new HashMap<String, Object>(); privilege.put("login_name", p.getLoginName()); List<String> permissions = new ArrayList<String>(); for (Permission permission : p.getPermissions()) permissions.add(permission.toString()); privilege.put("permissions", permissions); privileges.add(privilege); } m.put("privileges", privileges); List<Map<String, Object>> groups = new ArrayList<Map<String, Object>>(); for (SecurityGroup sg : accountService.getSecurityGroups()) { if (sg.getReadableTables().contains(tableName)) { Map<String, Object> group = new HashMap<String, Object>(); group.put("guid", sg.getGuid()); group.put("name", sg.getName()); group.put("description", sg.getDescription()); group.put("created", sg.getCreated()); group.put("updated", sg.getUpdated()); groups.add(group); } } m.put("security_groups", groups); if (verbose) setDetail(tableName, m); callback.onPush(new Row(m)); } private void setDetail(String tableName, Map<String, Object> m) { List<Date> logDates = new ArrayList<Date>(storage.getLogDates(tableName)); if (logDates.size() > 0) { m.put("min_day", logDates.get(logDates.size() - 1)); m.put("max_day", logDates.get(0)); } FilePath dir = storage.getTableDirectory(tableName); m.put("disk_usage", getConsumption(dir)); } private long getConsumption(FilePath dir) { long total = 0; FilePath[] files = dir.listFiles(); if (files == null) return 0; for (FilePath f : files) total += f.length(); return total; } private Map<String, Object> marshal(LogFileService lfs, StorageConfig storageConfig) { if (storageConfig == null) return null; Map<String, Object> m = new HashMap<String, Object>(); m.put("type", storageConfig.getType()); m.put("base_path", storageConfig.getBasePath()); Map<String, String> configs = new HashMap<String, String>(); for (TableConfig c : storageConfig.getConfigs()) { String value = null; if (c != null && c.getValues().size() > 1) value = c.getValues().toString(); else if (c != null) value = c.getValue(); configs.put(c.getKey(), value); } m.put("configs", configs); return m; } @Override public List<String> getFieldOrder() { return Arrays.asList("table", "compression", "crypto", "metadata", "replication_mode", "replication_table", "lock_owner", "lock_purpose", "lock_reentcnt", "retention_policy", "data_path"); } }