blob: 4ac2b122dd22b106756b5a16b4a9e1f91b02236d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.drill.exec.store.sys;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map.Entry;
import javax.annotation.Nullable;
import org.apache.drill.exec.ops.ExecutorFragmentContext;
import org.apache.drill.exec.proto.UserBitShared;
import org.apache.drill.exec.proto.UserBitShared.QueryProfile;
import org.apache.drill.exec.serialization.InstanceSerializer;
import org.apache.drill.exec.store.pojo.NonNullable;
import com.google.common.base.Function;
import com.google.common.collect.Iterators;
/**
* System table listing completed profiles as JSON documents
*/
public class ProfileJsonIterator extends ProfileIterator {
static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ProfileJsonIterator.class);
private final InstanceSerializer<QueryProfile> profileSerializer;
private final Iterator<ProfileJson> itr;
public ProfileJsonIterator(ExecutorFragmentContext context, int maxRecords) {
super(context, maxRecords);
//Holding a serializer (for JSON extract)
this.profileSerializer = profileStoreContext.getProfileStoreConfig().getSerializer();
this.itr = iterateProfileInfoJson();
}
@Override
protected Iterator<Entry<String, QueryProfile>> getProfiles(int skip, int take) {
return profileStoreContext.getCompletedProfileStore().getRange(skip, take);
}
//Returns an iterator for authorized profiles
private Iterator<ProfileJson> iterateProfileInfoJson() {
try {
//Transform authorized profiles to iterator for ProfileInfoJson
return transformJson(getAuthorizedProfiles(queryingUsername, isAdmin));
} catch (Exception e) {
logger.debug(e.getMessage(), e);
return Iterators.singletonIterator(ProfileJson.getDefault());
}
}
/**
* Iterating persistentStore as a iterator of {@link org.apache.drill.exec.store.sys.ProfileJsonIterator.ProfileJson}.
*/
private Iterator<ProfileJson> transformJson(Iterator<Entry<String, UserBitShared.QueryProfile>> all) {
return Iterators.transform(all, new Function<Entry<String, UserBitShared.QueryProfile>, ProfileJson>() {
@Nullable
@Override
public ProfileJson apply(@Nullable Entry<String, UserBitShared.QueryProfile> input) {
if (input == null || input.getValue() == null) {
return ProfileJson.getDefault();
}
//Constructing ProfileInfo
final String queryID = input.getKey();
String profileJson;
try {
profileJson = new String(profileSerializer.serialize(input.getValue()));
} catch (IOException e) {
logger.debug("Failed to serialize profile for: " + queryID, e);
profileJson = "{ 'message' : 'error (unable to serialize profile: "+ queryID +")' }";
}
return new ProfileJson(
queryID,
profileJson
);
}
});
}
@Override
public boolean hasNext() {
return itr.hasNext();
}
@Override
public Object next() {
return itr.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
public static class ProfileJson {
private static final String UNKNOWN_VALUE = "N/A";
private static final ProfileJson DEFAULT = new ProfileJson();
@NonNullable
public final String queryId;
public final String json;
public ProfileJson(String query_id, String profileJson) {
this.queryId = query_id;
this.json = profileJson;
}
private ProfileJson() {
this(UNKNOWN_VALUE, UNKNOWN_VALUE);
}
/**
* If unable to get ProfileInfo, use this default instance instead.
* @return the default instance
*/
public static ProfileJson getDefault() {
return DEFAULT;
}
}
}