
# 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.


#node configuration
UINODE='node03'
MLNODE='node04'
GWNODE='node16'
DBNAME='spot'

#hdfs - base user and data source config
HUSER='/user/spot'
NAME_NODE=''
WEB_PORT=50070
DNS_PATH=${HUSER}/${DSOURCE}/hive/y=${YR}/m=${MH}/d=${DY}/
PROXY_PATH=${HUSER}/${DSOURCE}/hive/y=${YR}/m=${MH}/d=${DY}/
FLOW_PATH=${HUSER}/${DSOURCE}/hive/y=${YR}/m=${MH}/d=${DY}/
HPATH=${HUSER}/${DSOURCE}/scored_results/${FDATE}

#impala config
IMPALA_DEM=node04
IMPALA_PORT=21050

#local fs base user and data source config
LUSER='/home/spot'
LPATH=${LUSER}/ml/${DSOURCE}/${FDATE}
RPATH=${LUSER}/ipython/user/${FDATE}
LIPATH=${LUSER}/ingest

#dns suspicious connects config
USER_DOMAIN=''

SPK_EXEC=''
SPK_EXEC_MEM=''
SPK_DRIVER_MEM=''
SPK_DRIVER_MAX_RESULTS=''
SPK_EXEC_CORES=''
SPK_DRIVER_MEM_OVERHEAD=''
SPK_EXEC_MEM_OVERHEAD=''
SPK_AUTO_BRDCST_JOIN_THR='10485760'

LDA_OPTIMIZER=''
LDA_ALPHA=''
LDA_BETA=''

PRECISION='64'
TOL='1e-6'
TOPIC_COUNT=20
DUPFACTOR=1000
