/**
* Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com)
*
* 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 com.linkedin.pinot.controller.api.restlet.resources;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.linkedin.pinot.common.data.DimensionFieldSpec;
import com.linkedin.pinot.common.data.FieldSpec;
import com.linkedin.pinot.common.data.MetricFieldSpec;
import com.linkedin.pinot.common.data.Schema;
import com.linkedin.pinot.controller.ControllerConf;
import com.linkedin.pinot.controller.helix.ControllerRequestURLBuilder;
import com.linkedin.pinot.controller.helix.ControllerTest;
import com.linkedin.pinot.controller.helix.ControllerTestUtils;
import java.io.IOException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class PinotSchemaRestletResourceTest extends ControllerTest {
private static final ObjectMapper objectMapper = new ObjectMapper();
ControllerRequestURLBuilder urlBuilder = ControllerRequestURLBuilder.baseUrl(CONTROLLER_BASE_API_URL);
@BeforeClass
public void setUp() {
startZk();
ControllerConf config = ControllerTestUtils.getDefaultControllerConfiguration();
config.setTableMinReplicas(1);
startController(config);
}
public JSONObject createDefaultSchema()
throws JSONException, JsonProcessingException {
JSONObject schemaJson = new JSONObject();
schemaJson.put("schemaName", "testSchema");
JSONArray dimFieldSpec = new JSONArray();
schemaJson.put("dimensionFieldSpecs", dimFieldSpec);
JSONArray metricFieldSpec = new JSONArray();
schemaJson.put("metricFieldSpecs", metricFieldSpec);
JSONObject timeFieldSpec = new JSONObject();
// schemaJson.put("timeFieldSpec", timeFieldSpec);
DimensionFieldSpec df = new DimensionFieldSpec("dimA", FieldSpec.DataType.STRING, true, "");
dimFieldSpec.put(new JSONObject(objectMapper.writeValueAsString(df)));
df = new DimensionFieldSpec("dimB", FieldSpec.DataType.LONG, true, 0);
dimFieldSpec.put(new JSONObject(objectMapper.writeValueAsString(df)));
MetricFieldSpec mf = new MetricFieldSpec("metricA", FieldSpec.DataType.INT, 0);
metricFieldSpec.put(new JSONObject(objectMapper.writeValueAsString(mf)));
mf = new MetricFieldSpec("metricB", FieldSpec.DataType.DOUBLE, -1);
metricFieldSpec.put(new JSONObject(objectMapper.writeValueAsString(mf)));
return schemaJson;
}
@Test
public void testBadContentType()
throws JSONException, JsonProcessingException {
JSONObject schema = createDefaultSchema();
try {
sendPostRequest(urlBuilder.forSchemaCreate(), schema.toString());
} catch (IOException e) {
Assert.assertTrue(e.getMessage().startsWith("Server returned HTTP response code: 415"), e.getMessage());
return;
}
// should not reach here
Assert.assertTrue(false);
}
@Test
public void testCreateUpdateSchema()
throws JSONException, IOException {
JSONObject schema = createDefaultSchema();
String url = urlBuilder.forSchemaCreate();
PostMethod postMethod = sendMultipartPostRequest(url, schema.toString());
Assert.assertEquals(postMethod.getStatusCode(), 200);
JSONArray dimSpecs = schema.getJSONArray("dimensionFieldSpecs");
DimensionFieldSpec df = new DimensionFieldSpec("NewColumn", FieldSpec.DataType.STRING, true);
dimSpecs.put(new JSONObject(objectMapper.writeValueAsString(df)));
postMethod = sendMultipartPostRequest(url, schema.toString());
Assert.assertEquals(postMethod.getStatusCode(), 200);
final String schemaName = schema.getString("schemaName");
String schemaStr = sendGetRequest(urlBuilder.forSchemaGet(schemaName));
Schema readSchema = Schema.fromString(schemaStr);
Schema inputSchema = Schema.fromString(schema.toString());
Assert.assertEquals(readSchema, inputSchema);
Assert.assertTrue(readSchema.getFieldSpecMap().containsKey("NewColumn"));
final String yetAnotherColumn = "YetAnotherColumn";
Assert.assertFalse(readSchema.getFieldSpecMap().containsKey(yetAnotherColumn));
df = new DimensionFieldSpec(yetAnotherColumn, FieldSpec.DataType.STRING, true);
dimSpecs.put(new JSONObject(objectMapper.writeValueAsString(df)));
PutMethod putMethod = sendMultipartPutRequest(urlBuilder.forSchemaUpdate(schemaName), schema.toString());
Assert.assertEquals(putMethod.getStatusCode(), 200);
// verify some more...
schemaStr = sendGetRequest(urlBuilder.forSchemaGet(schemaName));
readSchema = Schema.fromString(schemaStr);
inputSchema = Schema.fromString(schema.toString());
Assert.assertEquals(readSchema, inputSchema);
Assert.assertTrue(readSchema.getFieldSpecMap().containsKey(yetAnotherColumn));
// error cases
putMethod = sendMultipartPutRequest(urlBuilder.forSchemaUpdate(schemaName), schema.toString().substring(1));
// invalid json
Assert.assertEquals(putMethod.getStatusCode(), 400);
schema.put("schemaName", "differentSchemaName");
putMethod = sendMultipartPutRequest(urlBuilder.forSchemaUpdate(schemaName), schema.toString());
Assert.assertEquals(putMethod.getStatusCode(), 400);
}
}