org.apache.ranger.policyengine.perftest.v2.RangerPolicyFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ranger.policyengine.perftest.v2.RangerPolicyFactory.java

Source

/*
 * 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.ranger.policyengine.perftest.v2;

import static com.google.common.base.Preconditions.checkState;

import java.io.File;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
import org.apache.ranger.plugin.util.ServicePolicies;
import org.apache.ranger.policyengine.RangerAccessRequestDeserializer;
import org.apache.ranger.policyengine.RangerResourceDeserializer;

import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

/**
 * Factory for creating and wiring the object graph of {@link ServicePolicies} and {@link RangerAccessRequest}.
 */
public class RangerPolicyFactory {

    private static final double SUCCESSFUL_ACCESS_RATE = 0.7d;

    private static final Random RANDOM = new Random();

    private static final List<String> KNOWN_DATABASES = createList("database", 10);

    private static final List<String> KNOWN_TABLES = createList("tables", 100);

    private static final List<String> KNOWN_COLUMNS = createList("column", 1000);

    private static final List<String> KNOWN_USERS = createList("user", 1000);

    private static final List<String> RANDOM_VALUES = createList("random", 100);

    private static final List<String> ALWAYS_ALLOWED_ACCESS_TYPES = Arrays.asList("create", "select", "drop");

    /**
     * Returns a {@link ServicePolicies service policy} instance with containing the specified number of generated policies.
     * @param numberOfPolicies
     * @return
     */
    public static ServicePolicies createServicePolicy(int numberOfPolicies) {
        ServicePolicies servicePolicies = loadTemplate("/testdata/test_servicepolicies_hive.json",
                new TypeToken<ServicePolicies>() {
                }.getType());
        mutate(servicePolicies, numberOfPolicies);
        return servicePolicies;
    }

    private static void mutate(ServicePolicies servicePolicies, int numberOfPolicies) {
        servicePolicies.getPolicies().clear(); // reset
        servicePolicies.setPolicies(createPolicies(numberOfPolicies));
    }

    private static List<RangerPolicy> createPolicies(int numberOfPolicies) {
        List<RangerPolicy> policies = Lists.newArrayList();
        String template = readResourceFile("/testdata/single-policy-template.json");
        for (int i = 0; i < numberOfPolicies; i++) {
            policies.add(createPolicyFromTemplate(template, i, isAllowed()));
        }
        return policies;
    }

    private static RangerPolicy createPolicyFromTemplate(String template, long policyId, boolean isAllowed) {
        RangerPolicy rangerPolicy = buildGson().fromJson(template, RangerPolicy.class);
        rangerPolicy.setId(policyId);
        rangerPolicy.setName(String.format("generated policyname #%s", policyId));
        rangerPolicy.setResources(createRangerPolicyResourceMap(isAllowed));
        rangerPolicy.setPolicyItems(createPolicyItems(isAllowed));
        return rangerPolicy;
    }

    private static Map<String, RangerPolicyResource> createRangerPolicyResourceMap(boolean isAllowed) {
        RangerPolicyResource db = new RangerPolicyResource(
                isAllowed ? pickFewRandomly(KNOWN_DATABASES) : RANDOM_VALUES, false, false);
        RangerPolicyResource table = new RangerPolicyResource(
                isAllowed ? pickFewRandomly(KNOWN_TABLES) : RANDOM_VALUES, false, false);
        RangerPolicyResource column = new RangerPolicyResource(
                isAllowed ? pickFewRandomly(KNOWN_COLUMNS) : RANDOM_VALUES, false, false);
        return ImmutableMap.of("database", db, "table", table, "column", column);
    }

    private static List<RangerPolicyItem> createPolicyItems(boolean isAllowed) {
        List<RangerPolicyItem> policyItems = Lists.newArrayList();
        for (int i = 0; i < 15; i++) {
            policyItems.add(createPolicyItem(isAllowed));
        }
        return policyItems;
    }

    private static RangerPolicyItem createPolicyItem(boolean isAllowed) {
        RangerPolicyItem rangerPolicyItem = new RangerPolicyItem();
        rangerPolicyItem.setDelegateAdmin(false);
        rangerPolicyItem.setUsers(isAllowed ? KNOWN_USERS : RANDOM_VALUES);
        rangerPolicyItem.setAccesses(createAccesses(isAllowed));
        return rangerPolicyItem;
    }

    private static List<RangerPolicyItemAccess> createAccesses(boolean isAllowed) {
        List<RangerPolicyItemAccess> results = Lists.newArrayList();
        results.addAll(Lists.transform(isAllowed ? ALWAYS_ALLOWED_ACCESS_TYPES : RANDOM_VALUES,
                new Function<String, RangerPolicyItemAccess>() {
                    @Override
                    public RangerPolicyItemAccess apply(String input) {
                        return new RangerPolicyItemAccess(input, true);
                    }
                }));
        return results;
    }

    /**
     * Generates and returns a list of {@link RangerAccessRequest requests}
     * @param nubmerOfRequests the number of requests to generate.
     * @return
     */
    public static List<RangerAccessRequest> createAccessRequests(int nubmerOfRequests) {
        List<RangerAccessRequest> result = Lists.newArrayList();
        Gson gson = buildGson();
        String template = readResourceFile("/testdata/single-request-template.json");
        for (int i = 0; i < nubmerOfRequests; i++) {
            RangerAccessRequestImpl accessRequest = gson.fromJson(template, RangerAccessRequestImpl.class);
            result.add(mutate(accessRequest, isAllowed()));
        }
        return result;
    }

    /**
     * @return 10% of the time returns <code>true</code>, in which case the generated request policy should evaluate to true.
     */
    private static boolean isAllowed() {
        return RANDOM.nextDouble() < SUCCESSFUL_ACCESS_RATE;
    }

    private static RangerAccessRequest mutate(RangerAccessRequest template, boolean shouldEvaluateToTrue) {
        RangerAccessRequestImpl accessRequest = (RangerAccessRequestImpl) template;
        accessRequest.setResource(new RangerAccessResourceImpl(createResourceElements(shouldEvaluateToTrue)));
        accessRequest.setAccessType(pickOneRandomly(ALWAYS_ALLOWED_ACCESS_TYPES));
        accessRequest.setRequestData(null);
        accessRequest.setUser(pickOneRandomly(KNOWN_USERS));
        return accessRequest;
    }

    private static ImmutableMap<String, String> createResourceElements(boolean shouldEvaluateToTrue) {
        String database = String.format("db_%s", System.nanoTime());
        String table = String.format("table_%s", System.nanoTime());
        String column = String.format("column_%s", System.nanoTime());

        if (shouldEvaluateToTrue) {
            database = pickOneRandomly(KNOWN_DATABASES);
            table = pickOneRandomly(KNOWN_TABLES);
            column = pickOneRandomly(KNOWN_COLUMNS);
        }
        return ImmutableMap.of("database", database, "table", table, "column", column);
    }

    private static List<String> createList(String name, int n) {
        List<String> results = Lists.newArrayList();
        for (int i = 0; i < n; i++) {
            results.add(String.format("%s_%s", name, i));
        }
        return results;
    }

    private static String pickOneRandomly(Collection<String> list) {
        return Iterables.get(list, RANDOM.nextInt(list.size()));
    }

    private static List<String> pickFewRandomly(final List<String> list) {
        int resultSize = RANDOM.nextInt(list.size());

        Set<String> results = Sets.newHashSet();
        for (int i = 0; i < resultSize; i++) {
            results.add(pickOneRandomly(list));
        }
        return ImmutableList.copyOf(results);
    }

    private static <T> T loadTemplate(String file, Type targetType) {
        try {
            T model = buildGson().fromJson(readResourceFile(file), targetType);
            return model;
        } catch (Exception e) {
            throw Throwables.propagate(e);
        }
    }

    private static Gson buildGson() {
        GsonBuilder gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z");
        return gsonBuilder
                .registerTypeAdapter(RangerAccessRequest.class, new RangerAccessRequestDeserializer(gsonBuilder))
                .registerTypeAdapter(RangerAccessResource.class, new RangerResourceDeserializer(gsonBuilder))
                .setPrettyPrinting().create();
    }

    public static String readResourceFile(String fileName) {
        try {
            File f = new File(RangerPolicyFactory.class.getResource(fileName).toURI());
            checkState(f.exists() && f.isFile() && f.canRead());
            return Files.toString(f, Charsets.UTF_8);
        } catch (Exception e) {
            throw Throwables.propagate(e);
        }
    }

    public static RangerPolicyEngineOptions createPolicyEngineOption() {
        RangerPolicyEngineOptions policyEngineOptions = new RangerPolicyEngineOptions();
        policyEngineOptions.disableTagPolicyEvaluation = false;
        policyEngineOptions.evaluatorType = RangerPolicyEvaluator.EVALUATOR_TYPE_OPTIMIZED;
        policyEngineOptions.cacheAuditResults = false;
        policyEngineOptions.disableTrieLookupPrefilter = true;
        return policyEngineOptions;
    }
}