<commit_before>#!/usr/bin/env python
#<NAME> - Apr 2016
#This script refreshes a vdb
#requirements
#pip install --upgrade setuptools pip docopt delphixpy

#The below doc follows the POSIX compliant standards and allows us to use 
#this doc to also define our arguments for the script. This thing is brilliant.
"""Refresh a vdb

Usage:
  dx_refresh_db.py (--group <name> [--name <name>] | --all_vdbs | --host <name> [--group <name>])
                   [--timestamp_type <type>] [--timestamp <timepoint_semantic>]
                   [-d <identifier> | --engine <identifier> | --all]
                   [--debug] [--parallel <n>] [--poll <n>]
                   [--config <path_to_file>] [--logdir <path_to_file>]
  dx_refresh_db.py -h | --help | -v | --version

Refresh a Delphix VDB

Examples:
  dx_refresh_db.py --name "aseTest" --group "Analytics"
  dx_refresh_db.py --all_vdbs --host LINUXSOURCE --parallel 4 --debug -d landsharkengine
  dx_refresh_db.py --all_vdbs --group "Analytics" --all


Options:
  --name <name>             Name of the object you are refreshing.
  --all_vdbs                Refresh all VDBs that meet the filter criteria.
  --group <name>            Name of group in Delphix to execute against.
  --host <name>             Name of environment in Delphix to execute against.
  --timestamp_type <type>   The type of timestamp you are specifying.
                            Acceptable Values: TIME, SNAPSHOT
                            [default: SNAPSHOT]
  --timestamp <timepoint_semantic>
                            The Delphix semantic for the point in time on
                            the source from which you want to refresh your VDB.
                            Formats:
                            latest point in time or snapshot: LATEST
                            point in time: "YYYY-MM-DD HH24:MI:SS"
                            snapshot name: "@YYYY-MM-DDTHH24:MI:SS.ZZZ"
                            snapshot time from GUI: "YYYY-MM-DD HH24:MI"
                            [default: LATEST]
   -d <identifier>          Identifier of Delphix engine in dxtools.conf.
  --engine <type>           Alt Identifier of Delphix engine in dxtools.conf.
  --all                     Run against all engines.
  --debug                   Enable debug logging
  --parallel <n>            Limit number of jobs to maxjob
  --poll <n>                The number of seconds to wait between job polls
                            [default: 10]
  --config <path_to_file>   The path to the dxtools.conf file
                            [default: ./dxtools.conf]
  --logdir <path_to_file>    The path to the logfile you want to use.
                            [default: ./dx_refresh_db.log]
  -h --help                 Show this screen.
  -v --version              Show version.

"""

VERSION="v.0.0.006"


from docopt import docopt
import logging
from os.path import basename
import signal
import sys
import time
import traceback
import json

from multiprocessing import Process
from time import sleep, time

from delphixpy.v1_6_0.delphix_engine import DelphixEngine
from delphixpy.v1_6_0.exceptions import HttpError, JobError
from delphixpy.v1_6_0 import job_context
from delphixpy.v1_6_0.web import database, environment, group, job, source, user
from delphixpy.v1_6_0.web.vo import OracleRefreshParameters, RefreshParameters, TimeflowPointLocation, TimeflowPointSemantic, TimeflowPointTimestamp

def run_async(func):
    """
        http://code.activestate.com/recipes/576684-simple-threading-decorator/
        run_async(func)
            function decorator, intended to make "func" run in a separate
            thread (asynchronously).
            Returns the created Thread object

            E.g.:
            @run_async
            def task1():
                do_something

            @run_async
            def task2():
                do_something_too

            t1 = task1()
            t2 = task2()
            ...
            t1.join()
            t2.join()
    """
    from threading import Thread
    from functools import wraps

    @wraps(func)
    def async_func(*args, **kwargs):
        func_hl = Thread(target = func, args = args, kwargs = kwargs)
        func_hl.start()
        return func_hl

    return async_func
    
def find_all_databases_by_group_name(engine, server, group_name, exclude_js_container=True):
    """
    Easy way to quickly find databases by group name
    """

    #First search groups for the name specified and return its reference
    group_obj = find_obj_by_name(engine, server, group, group_name)
    if group_obj:
        databases=database.get_all(server, group=group_obj.reference, no_js_container_data_source=exclude_js_container)
        return databases

def find_database_by_name_and_group_name(engine, server, group_name, database_name):

    databases = find_all_databases_by_group_name(engine, server, group_name)

    for each in databases:
        if each.name == database_name:
            print_debug(engine["hostname"] + ": Found a match " + str(each.reference))
            return each
    print_info(engine["hostname"] + ": Unable to find \"" + database_name + "\" in " + group_name)

def find_obj_by_name(engine, server, f_class, obj_name):
    """
    Function to find objects by name and object class, and return object's reference as a string
    You might use this function to find objects like groups.
    """
    print_debug(engine["hostname"] + ": Searching objects in the " + f_class.__name__ + " class\n   for one named \"" + obj_name +"\"")
    obj_ref = ''

    all_objs = f_class.get_all(server)
    for obj in all_objs:
        if obj.name == obj_name:
            print_debug(engine["hostname"] + ": Found a match " + str(obj.reference))
            return obj
    print_info(engine["hostname"] + ": Unable to find a match")

def find_snapshot_by_database_and_name(engine, server, database_obj, snap_name):
    snapshots = snapshot.get_all(server, database=database_obj.reference)
    matches = []
    for snapshot_obj in snapshots:
        if str(snapshot_obj.name).startswith(arguments['--timestamp']):
            matches.append(snapshot_obj)
    if len(matches) == 1:
        print_debug(engine["hostname"] + ": Found one and only one match. This is good.")
        print_debug(engine["hostname"] + ": " + matches[0])
        return matches[0]
    elif len(matches) > 1:
        print_error("The name specified was not specific enough. More than one match found.")
        for each in matches:
            print_debug(engine["hostname"] + ": " + each.name)
    else:
        print_error("No matches found for the time specified")
    print_error("No matching snapshot found")

def find_snapshot_by_database_and_time(engine, server, database_obj, snap_time):
    snapshots = snapshot.get_all(server, database=database_obj.reference)
    matches = []
    for snapshot_obj in snapshots:
        if str(snapshot_obj.latest_change_point.timestamp).startswith(arguments['--timestamp']):
            matches.append(snapshot_obj)
    if len(matches) == 1:
        print_debug(engine["hostname"] + ": Found one and only one match. This is good.")
        print_debug(engine["hostname"] + ": " + matches[0])
        return matches[0]
    elif len(matches) > 1:
        print_error("The time specified was not specific enough. More than one match found.")
        print_debug(engine["hostname"] + ": " + matches)
    else:
        print_error("No matches found for the time specified")

def find_source_by_database(engine, server, database_obj):
    #The source tells us if the database is enabled/disables, virtual, vdb/dSource, or is a staging database.
    source_obj = source.get_all(server, database=database_obj.reference)
    #We'll just do a little sanity check here to ensure we only have a 1:1 result.<commit_msg>added snapshot object import. forced matches to string<commit_after>#!/usr/bin/env python
#<NAME> - Apr 2016
#This script refreshes a vdb
#requirements
#pip install --upgrade setuptools pip docopt delphixpy

#The below doc follows the POSIX compliant standards and allows us to use 
#this doc to also define our arguments for the script. This thing is brilliant.
"""Refresh a vdb

Usage:
  dx_refresh_db.py (--group <name> [--name <name>] | --all_vdbs | --host <name> [--group <name>])
                   [--timestamp_type <type>] [--timestamp <timepoint_semantic>]
                   [-d <identifier> | --engine <identifier> | --all]
                   [--debug] [--parallel <n>] [--poll <n>]
                   [--config <path_to_file>] [--logdir <path_to_file>]
  dx_refresh_db.py -h | --help | -v | --version

Refresh a Delphix VDB

Examples:
  dx_refresh_db.py --name "aseTest" --group "Analytics"
  dx_refresh_db.py --all_vdbs --host LINUXSOURCE --parallel 4 --debug -d landsharkengine
  dx_refresh_db.py --all_vdbs --group "Analytics" --all


Options:
  --name <name>             Name of the object you are refreshing.
  --all_vdbs                Refresh all VDBs that meet the filter criteria.
  --group <name>            Name of group in Delphix to execute against.
  --host <name>             Name of environment in Delphix to execute against.
  --timestamp_type <type>   The type of timestamp you are specifying.
                            Acceptable Values: TIME, SNAPSHOT
                            [default: SNAPSHOT]
  --timestamp <timepoint_semantic>
                            The Delphix semantic for the point in time on
                            the source from which you want to refresh your VDB.
                            Formats:
                            latest point in time or snapshot: LATEST
                            point in time: "YYYY-MM-DD HH24:MI:SS"
                            snapshot name: "@YYYY-MM-DDTHH24:MI:SS.ZZZ"
                            snapshot time from GUI: "YYYY-MM-DD HH24:MI"
                            [default: LATEST]
   -d <identifier>          Identifier of Delphix engine in dxtools.conf.
  --engine <type>           Alt Identifier of Delphix engine in dxtools.conf.
  --all                     Run against all engines.
  --debug                   Enable debug logging
  --parallel <n>            Limit number of jobs to maxjob
  --poll <n>                The number of seconds to wait between job polls
                            [default: 10]
  --config <path_to_file>   The path to the dxtools.conf file
                            [default: ./dxtools.conf]
  --logdir <path_to_file>    The path to the logfile you want to use.
                            [default: ./dx_refresh_db.log]
  -h --help                 Show this screen.
  -v --version              Show version.

"""

VERSION="v.0.0.006"


from docopt import docopt
import logging
from os.path import basename
import signal
import sys
import time
import traceback
import json

from multiprocessing import Process
from time import sleep, time

from delphixpy.v1_6_0.delphix_engine import DelphixEngine
from delphixpy.v1_6_0.exceptions import HttpError, JobError
from delphixpy.v1_6_0 import job_context
from delphixpy.v1_6_0.web import database, environment, group, job, source, user, snapshot
from delphixpy.v1_6_0.web.vo import OracleRefreshParameters, RefreshParameters, TimeflowPointLocation, TimeflowPointSemantic, TimeflowPointTimestamp

def run_async(func):
    """
        http://code.activestate.com/recipes/576684-simple-threading-decorator/
        run_async(func)
            function decorator, intended to make "func" run in a separate
            thread (asynchronously).
            Returns the created Thread object

            E.g.:
            @run_async
            def task1():
                do_something

            @run_async
            def task2():
                do_something_too

            t1 = task1()
            t2 = task2()
            ...
            t1.join()
            t2.join()
    """
    from threading import Thread
    from functools import wraps

    @wraps(func)
    def async_func(*args, **kwargs):
        func_hl = Thread(target = func, args = args, kwargs = kwargs)
        func_hl.start()
        return func_hl

    return async_func
    
def find_all_databases_by_group_name(engine, server, group_name, exclude_js_container=True):
    """
    Easy way to quickly find databases by group name
    """

    #First search groups for the name specified and return its reference
    group_obj = find_obj_by_name(engine, server, group, group_name)
    if group_obj:
        databases=database.get_all(server, group=group_obj.reference, no_js_container_data_source=exclude_js_container)
        return databases

def find_database_by_name_and_group_name(engine, server, group_name, database_name):

    databases = find_all_databases_by_group_name(engine, server, group_name)

    for each in databases:
        if each.name == database_name:
            print_debug(engine["hostname"] + ": Found a match " + str(each.reference))
            return each
    print_info(engine["hostname"] + ": Unable to find \"" + database_name + "\" in " + group_name)

def find_obj_by_name(engine, server, f_class, obj_name):
    """
    Function to find objects by name and object class, and return object's reference as a string
    You might use this function to find objects like groups.
    """
    print_debug(engine["hostname"] + ": Searching objects in the " + f_class.__name__ + " class\n   for one named \"" + obj_name +"\"")
    obj_ref = ''

    all_objs = f_class.get_all(server)
    for obj in all_objs:
        if obj.name == obj_name:
            print_debug(engine["hostname"] + ": Found a match " + str(obj.reference))
            return obj
    print_info(engine["hostname"] + ": Unable to find a match")

def find_snapshot_by_database_and_name(engine, server, database_obj, snap_name):
    snapshots = snapshot.get_all(server, database=database_obj.reference)
    matches = []
    for snapshot_obj in snapshots:
        if str(snapshot_obj.name).startswith(arguments['--timestamp']):
            matches.append(snapshot_obj)
    if len(matches) == 1:
        print_debug(engine["hostname"] + ": Found one and only one match. This is good.")
        print_debug(engine["hostname"] + ": " + str(matches[0]))
        return matches[0]
    elif len(matches) > 1:
        print_error("The name specified was not specific enough. More than one match found.")
        for each in matches:
            print_debug(engine["hostname"] + ": " + each.name)
    else:
        print_error("No matches found for the time specified")
    print_error("No matching snapshot found")

def find_snapshot_by_database_and_time(engine, server, database_obj, snap_time):
    snapshots = snapshot.get_all(server, database=database_obj.reference)
    matches = []
    for snapshot_obj in snapshots:
        if str(snapshot_obj.latest_change_point.timestamp).startswith(arguments['--timestamp']):
            matches.append(snapshot_obj)
    if len(matches) == 1:
        print_debug(engine["hostname"] + ": Found one and only one match. This is good.")
        print_debug(engine["hostname"] + ": " + str(matches[0]))
        return matches[0]
    elif len(matches) > 1:
        print_error("The time specified was not specific enough. More than one match found.")
        print_debug(engine["hostname"] + ": " + str(matches))
    else:
        print_error("No matches found for the time specified")

def find_source_by_database(engine, server, database_obj):
    #The source tells us if the database is enabled/disables, virtual, vdb/dSource, or is a staging database.
    source_obj = source.get_all(server, database=database_obj.reference)
    #We'll just do a little sanity check here to ensure we only have a 1:1 result.
{'fraction_non_alphanumeric': 0.09391702723339272, 'fraction_numerical': 0.007253754135912446, 'mean_word_length': 2.4137706342311036, 'pattern_counts': {'":': 22, '<': 51, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1305378', 'n_tokens_mistral': 4604, 'n_tokens_neox': 4497, 'n_words': 1405}