/*
* Copyright 2014-2015 CyberVision, 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.kaaproject.kaa.server.flume.sink.hdfs;
import com.google.common.base.Preconditions;
import org.apache.avro.Schema;
import org.apache.commons.io.FileUtils;
import org.apache.flume.Context;
import org.apache.flume.conf.Configurable;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.kaaproject.kaa.common.dto.logs.LogSchemaDto;
import org.kaaproject.kaa.server.flume.ConfigurationConstants;
import java.io.File;
public class AvroSchemaSource implements Configurable, ConfigurationConstants {
public static final String SCHEMA_SOURCE = "flume.avro.schema.source";
private static final String KAA_ADMIN_REST_API_LOG_SCHEMA = "/kaaAdmin/rest/api/logSchema/";
private static final String KAA_ADMIN_REST_API_CTL_SCHEMA = "/kaaAdmin/rest/api/CTL/"
+ "getFlatSchemaByCtlSchemaId?id=";
private String schemaSourceType;
private String kaaRestHost;
private int kaaRestPort;
private String kaaRestUser;
private String kaaRestPassword;
private String schemaLocalRoot;
private DefaultHttpClient httpClient;
private HttpHost restHost;
private HttpContext httpContext;
@Override
public void configure(Context context) {
schemaSourceType = context
.getString(CONFIG_AVRO_EVENT_SERIALIZER_SCHEMA_SOURCE,
DEFAULT_AVRO_EVENT_SERIALIZER_SCHEMA_SOURCE);
if (schemaSourceType.equals(SCHEMA_SOURCE_REST)) {
kaaRestHost = context.getString(CONFIG_KAA_REST_HOST, DEFAULT_KAA_REST_HOST);
kaaRestPort = context.getInteger(CONFIG_KAA_REST_PORT, DEFAULT_KAA_REST_PORT);
kaaRestUser = context.getString(CONFIG_KAA_REST_USER);
kaaRestPassword = context.getString(CONFIG_KAA_REST_PASSWORD);
Preconditions.checkArgument(kaaRestUser != null && kaaRestUser.length() > 0,
CONFIG_KAA_REST_USER + " must be specified for "
+ SCHEMA_SOURCE_REST + " avro schema source");
Preconditions.checkArgument(kaaRestPassword != null && kaaRestPassword.length() > 0,
CONFIG_KAA_REST_PASSWORD + " must be specified for "
+ SCHEMA_SOURCE_REST + " avro schema source");
initHttpRestClient();
} else {
schemaLocalRoot = context.getString(CONFIG_AVRO_EVENT_SERIALIZER_SCHEMA_LOCAL_ROOT);
Preconditions.checkArgument(schemaLocalRoot != null && schemaLocalRoot.length() > 0,
CONFIG_AVRO_EVENT_SERIALIZER_SCHEMA_LOCAL_ROOT
+ " must be specified for " + SCHEMA_SOURCE_LOCAL + " avro schema source");
}
}
private void initHttpRestClient() {
httpClient = new DefaultHttpClient();
restHost = new HttpHost(kaaRestHost, kaaRestPort, "http");
AuthCache authCache = new BasicAuthCache();
BasicScheme basicAuth = new BasicScheme();
authCache.put(restHost, basicAuth);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(kaaRestHost, kaaRestPort, AuthScope.ANY_REALM),
new UsernamePasswordCredentials(kaaRestUser, kaaRestPassword));
httpContext = new BasicHttpContext();
httpContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
httpContext.setAttribute(ClientContext.CREDS_PROVIDER, credsProvider);
}
/**
* Load avro schema by Kaa sink key.
*
* @param key the Kaa sink key
* @return schema
*/
public Schema loadByKey(KaaSinkKey key) throws Exception {
Schema schema = null;
String schemaString = null;
String logSchema = null;
if (schemaSourceType.equals(SCHEMA_SOURCE_REST)) {
HttpGet getRequest = new HttpGet(KAA_ADMIN_REST_API_LOG_SCHEMA + key.getApplicationToken()
+ "/" + key.getSchemaVersion());
HttpResponse httpResponse = httpClient.execute(restHost, getRequest, httpContext);
HttpEntity entity = httpResponse.getEntity();
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK && entity != null) {
String content = EntityUtils.toString(entity);
ObjectMapper mapper = new ObjectMapper();
LogSchemaDto logSchemaDto = mapper.readValue(content, LogSchemaDto.class);
HttpGet getCtlRequest = new HttpGet(KAA_ADMIN_REST_API_CTL_SCHEMA
+ logSchemaDto.getCtlSchemaId());
HttpResponse httpCtlResponse = httpClient.execute(restHost, getCtlRequest, httpContext);
HttpEntity ctlEntity = httpCtlResponse.getEntity();
if (httpCtlResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK
&& ctlEntity != null) {
String ctlContent = EntityUtils.toString(entity);
ObjectMapper ctlMapper = new ObjectMapper();
logSchema = ctlMapper.readValue(ctlContent, String.class);
}
schemaString = logSchema;
EntityUtils.consume(entity);
}
} else {
String applicationToken = key.getApplicationToken();
int version = key.getSchemaVersion();
String separator = System.getProperty("file.separator");
File schemaFile = new File(schemaLocalRoot + separator + applicationToken
+ separator + "schema_v" + version);
if (schemaFile.exists()) {
schemaString = FileUtils.readFileToString(schemaFile);
}
}
if (schemaString != null) {
Schema.Parser parser = new Schema.Parser();
schema = parser.parse(schemaString);
}
return schema;
}
}