Search in sources :

Example 31 with AbstractTableConfig

use of com.linkedin.pinot.common.config.AbstractTableConfig in project pinot by linkedin.

the class PinotTableRestletResource method post.

@Override
@Post("json")
public Representation post(Representation entity) {
    AbstractTableConfig config = null;
    try {
        String jsonRequest = entity.getText();
        config = AbstractTableConfig.init(jsonRequest);
        try {
            addTable(config);
        } catch (Exception e) {
            LOGGER.error("Caught exception while adding table", e);
            ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_ADD_ERROR, 1L);
            setStatus(Status.SERVER_ERROR_INTERNAL);
            return new StringRepresentation("Failed: " + e.getMessage());
        }
        return new StringRepresentation("Success");
    } catch (Exception e) {
        LOGGER.error("error reading/serializing requestJSON", e);
        setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
        return new StringRepresentation("Failed: " + e.getMessage());
    }
}
Also used : StringRepresentation(org.restlet.representation.StringRepresentation) AbstractTableConfig(com.linkedin.pinot.common.config.AbstractTableConfig) JsonProcessingException(org.codehaus.jackson.JsonProcessingException) JsonMappingException(org.codehaus.jackson.map.JsonMappingException) JSONException(org.json.JSONException) IOException(java.io.IOException) JsonParseException(org.codehaus.jackson.JsonParseException) Post(org.restlet.resource.Post)

Example 32 with AbstractTableConfig

use of com.linkedin.pinot.common.config.AbstractTableConfig in project pinot by linkedin.

the class PinotTableSchema method getTableSchema.

@HttpVerb("get")
@Summary("Gets schema for a table")
@Tags({ "schema", "table" })
@Paths({ "/tables/{tableName}/schema", "/tables/{tableName}/schema/" })
private Representation getTableSchema(@Parameter(name = "tableName", in = "path", description = "Table name for which to get the schema", required = true) String tableName) {
    if (_pinotHelixResourceManager.hasRealtimeTable(tableName)) {
        try {
            AbstractTableConfig config = _pinotHelixResourceManager.getTableConfig(tableName, TableType.REALTIME);
            return new StringRepresentation(_pinotHelixResourceManager.getSchema(config.getValidationConfig().getSchemaName()).getJSONSchema().toString());
        } catch (Exception e) {
            LOGGER.error("Caught exception while fetching schema for a realtime table : {} ", tableName, e);
            ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_SCHEMA_GET_ERROR, 1L);
            setStatus(Status.SERVER_ERROR_INTERNAL);
            return PinotSegmentUploadRestletResource.exceptionToStringRepresentation(e);
        }
    } else {
        AbstractTableConfig config;
        try {
            config = _pinotHelixResourceManager.getTableConfig(tableName, TableType.OFFLINE);
            String schemaName = config.getValidationConfig().getSchemaName();
            Schema schema = null;
            if (schemaName != null && !schemaName.isEmpty()) {
                schema = _pinotHelixResourceManager.getSchema(schemaName);
            }
            if (schema == null) {
                setStatus(Status.CLIENT_ERROR_NOT_FOUND);
                StringRepresentation repr = new StringRepresentation("{\"error\": \"Schema " + schemaName + " not found\"");
                repr.setMediaType(MediaType.APPLICATION_JSON);
                return repr;
            }
            return new StringRepresentation(schema.getJSONSchema().toString());
        } catch (Exception e) {
            LOGGER.error("Caught exception while fetching schema for a offline table : {} ", tableName, e);
            ControllerRestApplication.getControllerMetrics().addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_SCHEMA_GET_ERROR, 1L);
            setStatus(Status.SERVER_ERROR_INTERNAL);
            return PinotSegmentUploadRestletResource.exceptionToStringRepresentation(e);
        }
    }
}
Also used : StringRepresentation(org.restlet.representation.StringRepresentation) Schema(com.linkedin.pinot.common.data.Schema) AbstractTableConfig(com.linkedin.pinot.common.config.AbstractTableConfig) IOException(java.io.IOException) Summary(com.linkedin.pinot.common.restlet.swagger.Summary) HttpVerb(com.linkedin.pinot.common.restlet.swagger.HttpVerb) Paths(com.linkedin.pinot.common.restlet.swagger.Paths) Tags(com.linkedin.pinot.common.restlet.swagger.Tags)

Example 33 with AbstractTableConfig

use of com.linkedin.pinot.common.config.AbstractTableConfig in project pinot by linkedin.

the class PinotTableSegmentConfigs method updateSegmentConfig.

@Deprecated
@HttpVerb("put")
@Summary("DEPRECATED: Updates the segment configuration (validation and retention) for a table")
@Tags({ "table" })
@Paths({ "/tables/{tableName}/segmentConfigs" })
private Representation updateSegmentConfig(@Parameter(name = "tableName", in = "path", description = "The name of the table for which to update the segment configuration", required = true) String tableName, Representation entity) throws Exception {
    AbstractTableConfig config = AbstractTableConfig.init(entity.getText());
    _pinotHelixResourceManager.updateSegmentsValidationAndRetentionConfigFor(config.getTableName(), TableType.valueOf(config.getTableType().toUpperCase()), config.getValidationConfig());
    return new StringRepresentation("done");
}
Also used : StringRepresentation(org.restlet.representation.StringRepresentation) AbstractTableConfig(com.linkedin.pinot.common.config.AbstractTableConfig) Summary(com.linkedin.pinot.common.restlet.swagger.Summary) HttpVerb(com.linkedin.pinot.common.restlet.swagger.HttpVerb) Paths(com.linkedin.pinot.common.restlet.swagger.Paths) Tags(com.linkedin.pinot.common.restlet.swagger.Tags)

Example 34 with AbstractTableConfig

use of com.linkedin.pinot.common.config.AbstractTableConfig in project pinot by linkedin.

the class RoutingTableTest method testTableConfigRoutingTableSelector.

@Test
public void testTableConfigRoutingTableSelector() throws Exception {
    FakePropertyStore fakePropertyStore = new FakePropertyStore();
    TableConfigRoutingTableSelector tableConfigRoutingTableSelector = new TableConfigRoutingTableSelector();
    tableConfigRoutingTableSelector.init(null, fakePropertyStore);
    String propertyStoreEntry = "{\n" + "        \"tableName\":\"fakeTable\",\n" + "        \"segmentsConfig\": {\n" + "            \"retentionTimeUnit\":\"DAYS\",\n" + "            \"retentionTimeValue\":\"5\",\n" + "            \"segmentPushFrequency\":\"daily\",\n" + "            \"segmentPushType\":\"APPEND\",\n" + "            \"replication\": \"2\",\n" + "            \"schemaName\": \"fakeSchema\",\n" + "            \"timeColumnName\": \"time\",\n" + "            \"timeType\": \"MINUTES\",\n" + "            \"segmentAssignmentStrategy\": \"BalanceNumSegmentAssignmentStrategy\"\n" + "         },\n" + "         \"tableIndexConfig\": {\n" + "            \"invertedIndexColumns\": [\"columnA\",\"columnB\"],\n" + "            \"loadMode\": \"MMAP\",\n" + "            \"lazyLoad\": \"false\",\n" + "            \"streamConfigs\": {\n" + "               \"streamType\": \"kafka\",\n" + "               \"stream.kafka.consumer.type\": \"highLevel,simple\",\n" + "               \"stream.kafka.topic.name\": \"FakeTopic\",\n" + "               \"stream.kafka.decoder.class.name\": \"com.linkedin.pinot.core.realtime.impl.kafka.KafkaAvroMessageDecoder\",\n" + "\n" + "               \"stream.kafka.zk.broker.url\": \"fakezk:1234\",\n" + "               \"stream.kafka.hlc.zk.connect.string\": \"fakezk:1234\",\n" + "               \"stream.kafka.decoder.prop.schema.registry.rest.url\": \"fakeschemaregistry:1234\",\n" + "               \"stream.kafka.decoder.prop.schema.registry.schema.name\": \"FakeSchema\"\n" + "             }\n" + "          },\n" + "          \"tenants\": {\n" + "              \"broker\":\"fakebroker\",\n" + "              \"server\":\"fakeserver\"\n" + "          },\n" + "          \"tableType\":\"REALTIME\",\n" + "          \"metadata\": {\n" + "              \"customConfigs\": {\n" + "                  \"routing.llc.percentage\": \"50.0\"\n" + "               }\n" + "          }\n" + "    }\n" + "}";
    AbstractTableConfig tableConfig = AbstractTableConfig.init(propertyStoreEntry);
    fakePropertyStore.setContents("/CONFIGS/TABLE/fakeTable_REALTIME", AbstractTableConfig.toZnRecord(tableConfig));
    tableConfigRoutingTableSelector.registerTable("fakeTable_REALTIME");
    int llcCount = 0;
    for (int i = 0; i < 10000; ++i) {
        if (tableConfigRoutingTableSelector.shouldUseLLCRouting("fakeTable_REALTIME")) {
            llcCount++;
        }
    }
    Assert.assertTrue(4500 <= llcCount && llcCount <= 5500, "Expected approximately 50% probability of picking LLC, got " + llcCount / 100.0 + " %");
    tableConfig.getCustomConfigs().setCustomConfigs(Collections.singletonMap("routing.llc.percentage", "0"));
    fakePropertyStore.setContents("/CONFIGS/TABLE/fakeTable_REALTIME", AbstractTableConfig.toZnRecord(tableConfig));
    llcCount = 0;
    for (int i = 0; i < 10000; ++i) {
        if (tableConfigRoutingTableSelector.shouldUseLLCRouting("fakeTable_REALTIME")) {
            llcCount++;
        }
    }
    Assert.assertEquals(llcCount, 0, "Expected 0% probability of picking LLC, got " + llcCount / 100.0 + " %");
    tableConfig.getCustomConfigs().setCustomConfigs(Collections.singletonMap("routing.llc.percentage", "100"));
    fakePropertyStore.setContents("/CONFIGS/TABLE/fakeTable_REALTIME", AbstractTableConfig.toZnRecord(tableConfig));
    llcCount = 0;
    for (int i = 0; i < 10000; ++i) {
        if (tableConfigRoutingTableSelector.shouldUseLLCRouting("fakeTable_REALTIME")) {
            llcCount++;
        }
    }
    Assert.assertEquals(llcCount, 10000, "Expected 100% probability of picking LLC, got " + llcCount / 100.0 + " %");
}
Also used : AbstractTableConfig(com.linkedin.pinot.common.config.AbstractTableConfig) Test(org.testng.annotations.Test)

Example 35 with AbstractTableConfig

use of com.linkedin.pinot.common.config.AbstractTableConfig in project pinot by linkedin.

the class HelixExternalViewBasedTimeBoundaryService method updateTimeBoundaryService.

public synchronized void updateTimeBoundaryService(ExternalView externalView) {
    if (_propertyStore == null) {
        return;
    }
    String tableName = externalView.getResourceName();
    // Do nothing for realtime table.
    if (TableNameBuilder.getTableTypeFromTableName(tableName) == TableType.REALTIME) {
        return;
    }
    Set<String> offlineSegmentsServing = externalView.getPartitionSet();
    if (offlineSegmentsServing.isEmpty()) {
        LOGGER.info("Skipping updating time boundary service for table '{}' with no offline segments.", tableName);
        return;
    }
    AbstractTableConfig offlineTableConfig = ZKMetadataProvider.getOfflineTableConfig(_propertyStore, tableName);
    String timeType = offlineTableConfig.getValidationConfig().getTimeType();
    TimeUnit tableTimeUnit = getTimeUnitFromString(timeType);
    if (tableTimeUnit == null) {
        LOGGER.info("Skipping updating time boundary service for table '{}' with null timeUnit, config time type: {}.", tableName, timeType);
        return;
    }
    // Bulk reading all segment zk-metadata at once is more efficient than reading one at a time.
    List<OfflineSegmentZKMetadata> segmentZKMetadataList = ZKMetadataProvider.getOfflineSegmentZKMetadataListForTable(_propertyStore, tableName);
    long maxTimeValue = computeMaxSegmentEndTimeForTable(segmentZKMetadataList, tableTimeUnit);
    TimeBoundaryInfo timeBoundaryInfo = new TimeBoundaryInfo();
    timeBoundaryInfo.setTimeColumn(offlineTableConfig.getValidationConfig().getTimeColumnName());
    timeBoundaryInfo.setTimeValue(Long.toString(maxTimeValue));
    _timeBoundaryInfoMap.put(tableName, timeBoundaryInfo);
    LOGGER.info("Updated time boundary service for table '{}', maxTime: {}", tableName, maxTimeValue);
}
Also used : OfflineSegmentZKMetadata(com.linkedin.pinot.common.metadata.segment.OfflineSegmentZKMetadata) TimeUnit(java.util.concurrent.TimeUnit) AbstractTableConfig(com.linkedin.pinot.common.config.AbstractTableConfig)

Aggregations

AbstractTableConfig (com.linkedin.pinot.common.config.AbstractTableConfig)53 ZNRecord (org.apache.helix.ZNRecord)10 Test (org.testng.annotations.Test)10 IdealState (org.apache.helix.model.IdealState)9 ArrayList (java.util.ArrayList)8 JSONObject (org.json.JSONObject)8 HttpVerb (com.linkedin.pinot.common.restlet.swagger.HttpVerb)7 Paths (com.linkedin.pinot.common.restlet.swagger.Paths)7 Summary (com.linkedin.pinot.common.restlet.swagger.Summary)7 Tags (com.linkedin.pinot.common.restlet.swagger.Tags)7 IOException (java.io.IOException)7 HashMap (java.util.HashMap)7 StringRepresentation (org.restlet.representation.StringRepresentation)7 BeforeTest (org.testng.annotations.BeforeTest)7 TableNameBuilder (com.linkedin.pinot.common.config.TableNameBuilder)6 Schema (com.linkedin.pinot.common.data.Schema)6 IndexingConfig (com.linkedin.pinot.common.config.IndexingConfig)5 KafkaStreamMetadata (com.linkedin.pinot.common.metadata.stream.KafkaStreamMetadata)4 JSONException (org.json.JSONException)4 SegmentsValidationAndRetentionConfig (com.linkedin.pinot.common.config.SegmentsValidationAndRetentionConfig)3