/*-
 * ============LICENSE_START=======================================================
 * OSAM
 * ================================================================================
 * Copyright (C) 2018 AT&T
 * ================================================================================
 * 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.
 * ============LICENSE_END=========================================================
 */



package org.onap.osam.properties;

import org.togglz.core.Feature;
import org.togglz.core.context.FeatureContext;

public enum Features implements Feature {


    FLAG_ASYNC_JOBS,
    FLAG_REGION_ID_FROM_REMOTE,
    CREATE_INSTANCE_TEST,
    EMPTY_DRAWING_BOARD_TEST,
    FLAG_ADVANCED_PORTS_FILTER,
    FLAG_ADD_MSO_TESTAPI_FIELD,
    FLAG_ASYNC_INSTANTIATION,
    FLAG_SERVICE_MODEL_CACHE,
    FLAG_UNASSIGN_SERVICE,
    FLAG_NETWORK_TO_ASYNC_INSTANTIATION,
    FLAG_COLLECTION_RESOURCE_SUPPORT,
    FLAG_SHOW_ASSIGNMENTS,
    FLAG_SHOW_VERIFY_SERVICE,
    FLAG_SETTING_DEFAULTS_IN_DRAWING_BOARD,
    FLAG_PNP_INSTANTIATION;

    public boolean isActive() {
        return FeatureContext.getFeatureManager().isActive(this);
    }

}
