| /* |
| * 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.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.apache.drill.exec.ops.FragmentContext; |
| import org.apache.drill.exec.server.options.DrillConfigIterator; |
| import org.apache.drill.exec.server.options.OptionManager; |
| import org.apache.drill.exec.server.options.OptionValue; |
| import org.apache.drill.exec.server.options.OptionValue.AccessibleScopes; |
| import org.apache.drill.exec.server.options.OptionValue.Kind; |
| import org.apache.drill.exec.server.options.OptionValue.OptionScope; |
| import org.apache.drill.exec.store.pojo.NonNullable; |
| |
| import com.google.common.collect.Iterators; |
| import com.google.common.collect.Lists; |
| |
| public class OptionIterator implements Iterator<Object> { |
| // private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(OptionIterator.class); |
| |
| enum Mode { |
| BOOT, |
| // These represent System/Session options that are public. These are available for everyone to change and are considered safe to change. |
| SYS_SESS_PUBLIC, |
| // These represent System/Session options that are internal. These are segregated from the public options and are not visible in the same tables and rest endpoints as public |
| // options. These are technically available for anyone to change, but users are discouraged from doing so unless they absolutely know what they are doing. The general purpose |
| // for internal options is to enable support to easily debug. |
| SYS_SESS_INTERNAL |
| }; |
| |
| private final OptionManager fragmentOptions; |
| private final Iterator<OptionValue> mergedOptions; |
| |
| public OptionIterator(FragmentContext context, Mode mode){ |
| final DrillConfigIterator configOptions = new DrillConfigIterator(context.getConfig()); |
| fragmentOptions = context.getOptions(); |
| final Iterator<OptionValue> optionList; |
| switch(mode){ |
| case BOOT: |
| optionList = configOptions.iterator(); |
| break; |
| case SYS_SESS_PUBLIC: |
| optionList = fragmentOptions.getPublicOptionList().iterator(); |
| break; |
| case SYS_SESS_INTERNAL: |
| optionList = fragmentOptions.getInternalOptionList().iterator(); |
| break; |
| default: |
| optionList = Iterators.concat(configOptions.iterator(), fragmentOptions.iterator()); |
| } |
| |
| List<OptionValue> values = Lists.newArrayList(optionList); |
| Collections.sort(values); |
| mergedOptions = values.iterator(); |
| |
| } |
| |
| @Override |
| public boolean hasNext() { |
| return mergedOptions.hasNext(); |
| } |
| |
| @Override |
| public OptionValueWrapper next() { |
| final OptionValue value = mergedOptions.next(); |
| final Status status; |
| |
| if (value.accessibleScopes == AccessibleScopes.BOOT) { |
| status = Status.BOOT; |
| } else { |
| final OptionValue def = fragmentOptions.getDefault(value.name); |
| if (value.equalsIgnoreType(def)) { |
| status = Status.DEFAULT; |
| } else { |
| status = Status.CHANGED; |
| } |
| } |
| return new OptionValueWrapper(value.name, value.kind, value.accessibleScopes, value.scope, value.num_val, value.string_val, |
| value.bool_val, value.float_val, status); |
| } |
| |
| public enum Status { |
| BOOT, DEFAULT, CHANGED |
| } |
| |
| /** |
| * Wrapper class for OptionValue to add Status |
| */ |
| public static class OptionValueWrapper { |
| |
| @NonNullable |
| public final String name; |
| @NonNullable |
| public final Kind kind; |
| @NonNullable |
| public final AccessibleScopes accessibleScopes; |
| @NonNullable |
| public final OptionScope optionScope; |
| @NonNullable |
| public final Status status; |
| public final Long num_val; |
| public final String string_val; |
| public final Boolean bool_val; |
| public final Double float_val; |
| |
| public OptionValueWrapper(final String name, final Kind kind, final OptionValue.AccessibleScopes type, final OptionScope scope, final Long num_val, |
| final String string_val, final Boolean bool_val, final Double float_val, |
| final Status status) { |
| this.name = name; |
| this.kind = kind; |
| this.accessibleScopes = type; |
| this.optionScope = scope; |
| this.num_val = num_val; |
| this.string_val = string_val; |
| this.bool_val = bool_val; |
| this.float_val = float_val; |
| this.status = status; |
| } |
| } |
| |
| @Override |
| public void remove() { |
| throw new UnsupportedOperationException(); |
| } |
| } |