private void queueEmptyMaybeFlush() {
        if (PERIODIC_FORCE_FLUSH) {
            long currentTime = time.get();
            /* Try not to flush more than once every x times per mili-seconds time period. */
            if ((currentTime - lastFlushTime) > FORCE_FLUSH_AFTER_THIS_MANY_MILI_SECONDS) {

                /* If the writer had things to flush, and we flushed then
                increment the number of flushes.
                 */
                if (writer.syncToDisk()) { //could take 100 ms to 1 second
                    this.numberOfFlushesTotal.incrementAndGet();
                }
                /* We update the flush time no matter what. */
                lastFlushTime = time.get();
            }
        }
    }

If we detect that the in-coming transfer outputDataQueue channel is empty
then it could be an excellent time to sync to disk.

If we detect that the in - coming transfer outputDataQueue channel is empty then it could be an excellent time to sync to disk .


private void startMonitor() {

        final ScheduledExecutorService monitor = Executors.newScheduledThreadPool(2,
                new ThreadFactory() {
                    @Override
                    public Thread newThread(Runnable runnable) {
                        Thread thread = new Thread(runnable);
                        thread.setPriority(Thread.NORM_PRIORITY + 1);
                        return thread;
                    }
                }
        );

        monitorFuture = monitor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                monitor();
            }
        }, MONITOR_INTERVAL_SECONDS, MONITOR_INTERVAL_SECONDS, TimeUnit.SECONDS);

        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                System.err.println("shutting down....");
                monitor();
            }
        }));

    }

private
void
startMonitor
(
)
{
final
ScheduledExecutorService
monitor
=
Executors
.
newScheduledThreadPool
(
2
,
new
ThreadFactory
(
)
{
@
Override
public
Thread
newThread
(
Runnable
runnable
)
{
Thread
thread
=
new
Thread
(
runnable
)
;
thread
.
setPriority
(
Thread
.
NORM_PRIORITY
+
1
)
;
return
thread
;
}
}
)
;
monitorFuture
=
monitor
.
scheduleAtFixedRate
(
new
Runnable
(
)
{
@
Override
public
void
run
(
)
{
monitor
(
)
;
}
}
,
MONITOR_INTERVAL_SECONDS
,
MONITOR_INTERVAL_SECONDS
,
TimeUnit
.
SECONDS
)
;
Runtime
.
getRuntime
(
)
.
addShutdownHook
(
new
Thread
(
new
Runnable
(
)
{
@
Override
public
void
run
(
)
{
System
.
err
.
println
(
"shutting down...."
)
;
monitor
(
)
;
}
}
)
)
;
}


public void start(final TimeAware receiver) {

        //This starts itself up again every 1/2 second if something really bad
        //happens like disk full. As soon as the problem gets corrected
        //then things start working again...happy day.    Only
        // one is running per instance of CollectionManagerImpl.
        writerFuture =
                scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
                    @Override
                    public void run() {
                        processWrites();
                    }
                }, 0, 500, TimeUnit.MILLISECONDS);

        startMonitor();

        tickTock =
                this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
                    @Override
                    public void run() {

                        long time = System.nanoTime() / 1_000_000;
                        if (receiver != null) {
                            receiver.tick(time);
                        }
                        tick(time);

                    }
                }, 0, 20, TimeUnit.MILLISECONDS);

    }


@Override
    public final Object get( Object key ) {

        Object object=null;

        /* if the map is null, then we create it. */
        if ( map == null ) {
                buildMap ();
        }
        object = map.get ( key );

        lazyChopIfNeeded ( object );

        return object;
    }

Gets the item by key from the mapping.

@param key to lookupWithDefault
@return


private ResultSet mainQueryPlan( Criteria[] expressions ) {

        ResultSetInternal results = new ResultSetImpl( this.fields );

        if (expressions == null || expressions.length == 0) {
            results.addResults ( searchableCollection.all() );
        }

        /* I am sure this looked easy to read when I wrote it.
         * If there is only one expression and first expression is a group then
         * the group is that first expression otherwise wrap
         * all of the expressions in an and clause. */
        Group group = expressions.length ==
                1 && expressions[ 0 ] instanceof Group
                ? ( Group ) expressions[ 0 ] : ObjectFilter.and( expressions );

        /**
         * Run the filter on the group.
         */
        doFilterGroup( group, results );

        return results;
    }

/**
         * Run the filter on the group.
         */

This is the main criteria plan in case the name was not
obvious.

@param expressions
@return
@author Rick Hightower

This is the main criteria plan in case the name was not obvious .


private void doFilterGroup( Group group, ResultSetInternal results ) {
        /* The group was n or group so handle it that way. */
        if ( group.getGrouping() == Grouping.OR ) {
            /* nice short method name, or. */
            or( group.getExpressions(), fields, results );
        } else {
            /* create a result internal (why?), wrap the fields in the result set
            internal, and pass that to the and method.
             */
            ResultSetInternal resultsForAnd = new ResultSetImpl( fields );
            and( group.getExpressions(), fields, resultsForAnd );
            results.addResults( resultsForAnd.asList() );
        }
    }

Run the filter on the group.

@param group   here is the group
@param results here are the results


public void tick(long time) {
        this.time.set(time);
        long startTime = fileStartTime.get();
        long duration = time - startTime;

        if (duration > FILE_TIMEOUT_MILISECONDS) {
            fileTimeOut.set(true);
        }
    }

public void tick ( long time ) { this . time . set ( time ) ; long startTime = fileStartTime . get ( ) ; long duration = time - startTime ; if ( duration > FILE_TIMEOUT_MILISECONDS ) { fileTimeOut . set ( true ) ; } }


public boolean syncToDisk() {

        /** if we have a stream and we are dirty then flush. */
        if (outputStream != null && dirty) {

            try {
                //outputStream.flush ();

                if (outputStream instanceof FileChannel) {
                    FileChannel channel = (FileChannel) outputStream;
                    channel.force(true);
                }
                dirty = false;
                return true;
            } catch (Exception ex) {
                cleanupOutputStream();
                return false;
            }
        } else {
            return false;
        }
    }


private void cleanupOutputStream() {

        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException e) {

                e.printStackTrace(System.err);
            } finally {
                outputStream = null;
            }
        }

    }

private void cleanupOutputStream ( ) { if ( outputStream != null ) { try { outputStream . close ( ) ; } catch ( IOException e ) { e . printStackTrace ( System . err ) ; } finally { outputStream = null ; } } }


public void nextBufferToWrite(final ByteBuffer bufferOut) throws InterruptedException {
        dirty = true;
        final int size = bufferOut.limit();

        write(bufferOut);

        /* only increment bytes transferred after a successful write. */
        if (!error.get()) {
            totalBytesTransferred += size;
            bytesTransferred += size;
            bytesSinceLastFlush += size;
            buffersSent++;
        }

        if (this.bytesTransferred >= FILE_SIZE_BYTES || fileTimeOut.get()) {

            try {
                outputStream.close();
            } catch (IOException e) {
                cleanupOutputStream();
                e.printStackTrace(System.err);
            } finally {
                outputStream = null;
            }
        }

    }

Writes a buffer of data to the log system.

Writes a buffer of data to the log system .


private void write(final ByteBuffer bufferOut) throws InterruptedException {

        initOutputStream();
        try {
            if (outputStream != null) {

                outputStream.write(bufferOut);

            } else {
                error.set(true);
            }

            if (bytesSinceLastFlush > FLUSH_EVERY_N_BYTES) {
                syncToDisk();
                bytesSinceLastFlush = 0;
            }
        } catch (ClosedByInterruptException cbie) {
            throw new InterruptedException("File closed by interruption");
        } catch (Exception e) {
            cleanupOutputStream();
            error.set(true);
            e.printStackTrace(System.err);

            diagnose();

            Exceptions.handle(e);
        }

    }

private
void
write
(
final
ByteBuffer
bufferOut
)
throws
InterruptedException
{
initOutputStream
(
)
;
try
{
if
(
outputStream
!=
)
{
outputStream
.
write
(
bufferOut
)
;
}
else
{
error
.
set
(
true
)
;
}
if
(
bytesSinceLastFlush
>
FLUSH_EVERY_N_BYTES
)
{
syncToDisk
(
)
;
bytesSinceLastFlush
=
0
;
}
}
catch
(
ClosedByInterruptException
cbie
)
{
throw
new
InterruptedException
(
"File closed by interruption"
)
;
}
catch
(
Exception
e
)
{
cleanupOutputStream
(
)
;
error
.
set
(
true
)
;
e
.
printStackTrace
(
System
.
err
)
;
diagnose
(
)
;
Exceptions
.
handle
(
e
)
;
}
}


private void initOutputStream() {

        long time = this.time.get();

        if (error.get() || this.totalBytesTransferred == 0) {
            cleanupOutputStream();
            error.set(false);
            time = System.nanoTime() / 1_000_000;
        }

        if (outputStream != null) {
            return;
        }

        fileName = LogFilesConfig.getLogFileName(FORMAT_PATTERN, outputDirPath(), numFiles, time, SERVER_NAME);
        try {
            fileTimeOut.set(false);
            outputStream = streamCreator();

            fileStartTime.set(time);

            bytesTransferred = 0;
            bytesSinceLastFlush = 0;

        } catch (Exception ex) {
            cleanupOutputStream();
            error.set(true);
            Exceptions.handle(ex);
        } finally {
            numFiles++;
        }
    }

private void initOutputStream ( ) { long time = this . time . get ( ) ; if ( error . get ( ) || this . totalBytesTransferred == 0 ) { cleanupOutputStream ( ) ; error . set ( false ) ; time = System . nanoTime ( ) / 1_000_000 ; } if ( outputStream != null ) { return ; } fileName = LogFilesConfig . getLogFileName ( FORMAT_PATTERN , outputDirPath ( ) , numFiles , time , SERVER_NAME ) ; try { fileTimeOut . set ( false ) ; outputStream = streamCreator ( ) ; fileStartTime . set ( time ) ; bytesTransferred = 0 ; bytesSinceLastFlush = 0 ; } catch ( Exception ex ) { cleanupOutputStream ( ) ; error . set ( true ) ; Exceptions . handle ( ex ) ; } finally { numFiles ++ ; } }


public void putAll(Map<K, V> values) {
        Set<Map.Entry<K, V>> entries = values.entrySet();
        Map<String, String> map = new HashMap<>(values.size());

        for (Map.Entry<K, V> entry : entries) {
            map.put(toKeyString(entry.getKey()), toValueString(entry.getValue()));
        }

        store.putAll(map);
    }

public void putAll ( Map < K , V > values ) { Set < Map . Entry < K , V > > entries = values . entrySet ( ) ; Map < String , String > map = new HashMap <> ( values . size ( ) ) ; for ( Map . Entry < K , V > entry : entries ) { map . put ( toKeyString ( entry . getKey ( ) ) , toValueString ( entry . getValue ( ) ) ) ; } store . putAll ( map ) ; }

Put all of these values in the key value store.

@param values values

Put all of these values in the key value store .


protected byte[] toKeyBytes(K key) {

        byte[] keyBytes = keyCache.get(key);
        if (keyBytes == null) {
            keyBytes = this.keyToByteArrayConverter.apply(key);
            keyCache.put(key, keyBytes);
        }
        return keyBytes;

    }

protected byte [ ] toKeyBytes ( K key ) { byte [ ] keyBytes = keyCache . get ( key ) ; if ( keyBytes == null ) { keyBytes = this . keyToByteArrayConverter . apply ( key ) ; keyCache . put ( key , keyBytes ) ; } return keyBytes ; }

Convert a String key to bytes.

@param key key to convert
@return value


public List<ValidatorMetaData> readMetaData( Class<?> clazz, String propertyName ) {

        /* Load the properties file. */
        Properties props = loadMetaDataPropsFile( clazz );
        /* Get the raw validation data for the given property. */
        String unparsedString = props.getProperty( propertyName );
        /* Parse the string into a list of ValidationMetaData. */
        return extractMetaDataFromString( clazz, propertyName, unparsedString );
    }

Read the meta-data from a properties file.

Read the meta - data from a properties file .


private List<ValidatorMetaData> extractMetaDataFromString( Class<?> clazz,
                                                               String propertyName, String unparsedString ) {
        String propertyKey = clazz.getName() + "." + propertyName;

        /* See if we parsed this bad boy already. */
        List<ValidatorMetaData> validatorMetaDataList =
                metaDataCache.get( propertyKey );

        /* If we did not find the list, then we have some work to do.*/
        if ( validatorMetaDataList == null ) {
            /* Initialize a new list. */
            validatorMetaDataList = new ArrayList<ValidatorMetaData>();

            /* Remember we have a string that looks like this:
             * required; length min=10, max=100
             * So we need to split on semi-colon.
             */
            String[] validatorsParts = unparsedString.split( "[;]" );

            /* Now we have the two strings as follows:
             *  ["required",
             *  ["length min=10, max=100"]
             *
             */
            for ( String validatorString : validatorsParts ) {
                ValidatorMetaData validatorMetaData = new ValidatorMetaData();
                validatorMetaDataList.add( validatorMetaData );

                /* Now we split one of the string (we will use length)
                 * as follows:
                 * parts=["length", "min=10", "max=100"]
                 * */
                String[] parts = validatorString.trim().split( "[ ,]" );

                /* The first part is the name of the validation,
                 * e.g., "length".
                 *
                 */
                validatorMetaData.setName( parts[ 0 ] );

                /* If the string has more than one part, then there must
                 * be arguments as in: ["min=10", "max=100"]
                 *
                 * Parse the arguments and addObject them to the list as well.
                 */
                if ( parts.length > 1 ) {

                    /* This line converts:
                     *
                     * ["length", "min=10", "max=100"]
                     *
                     * into:
                     *
                     * ["min=10", "max=100"]
                     */
                    List<String> values =
                            Arrays.asList( parts ).subList( 1, parts.length );

                    /* For each value convert it into name value pairs. */
                    for ( String value : values ) {

                        if ( value.indexOf( "=" ) != -1 ) {
                            /* Split "min=10" into ["min", "10"] */
                            String[] valueParts = value.split( "[=]" );
                            /* Stick this value into validatorMetaData's
                             * list of properties.
                             */
                            validatorMetaData.getProperties().put(
                                    valueParts[ 0 ], valueParts[ 1 ] );
                        }
                    }
                }
            }
            metaDataCache.put( propertyKey, validatorMetaDataList );
        }
        return validatorMetaDataList;
    }

This method extracts meta-data from a string.

@param clazz
@param propertyName
@param unparsedString
@return

This method extracts meta - data from a string .


public List<ValidatorMetaData> readMetaData( Class<?> clazz, String propertyName ) {

        /* Generate a key to the cache based on the classname and the propertyName. */
        String propertyKey = clazz.getName() + "." + propertyName;

        /* Look up the validation meta data in the cache. */
        List<ValidatorMetaData> validatorMetaDataList = metaDataCache.get( propertyKey );

        /* If the meta-data was not found, then generate it. */
        if ( validatorMetaDataList == null ) { // if not found
            validatorMetaDataList = extractValidatorMetaData( clazz, propertyName, validatorMetaDataList );
            /* Put it in the cache to avoid the processing in the future.
             * Design notes: The processing does a lot of reflection, there
             * is no need to do this each time.
             */
            metaDataCache.put( propertyKey, validatorMetaDataList );
        }

        return validatorMetaDataList;

    }

Read the meta-data from annotation. This copies the meta-data
from the annotation into a POJO. It first checks the meta-data cache,
if the meta data is not found in the cache it then reads it from the
class.

@param clazz        The class that contains the annotation.
@param propertyName The name of the property that we are reading
the annotation meta-data from.

Read the meta - data from annotation . This copies the meta - data from the annotation into a POJO . It first checks the meta - data cache if the meta data is not found in the cache it then reads it from the class .


private List<ValidatorMetaData> extractValidatorMetaData( Class<?> clazz, String propertyName, List<ValidatorMetaData> validatorMetaDataList ) {
        /* If the meta-data was not found, then generate it. */
        if ( validatorMetaDataList == null ) { // if not found
            /* Read the annotation from the class based on the property name. */
            Collection<AnnotationData> annotations = Annotations.getAnnotationDataForFieldAndProperty( clazz, propertyName, this.validationAnnotationPackages );

            /* Extract the POJO based meta-data from the annotation. */
            validatorMetaDataList =
                    extractMetaDataFromAnnotations( annotations );

        }
        return validatorMetaDataList;
    }

Extract BaseValidator Meta Data.

@param clazz                 class
@param propertyName          property name
@param validatorMetaDataList validatorMetaDataList
@return validator meta data


private List<ValidatorMetaData> extractMetaDataFromAnnotations(
            Collection<AnnotationData> annotations ) {
        List<ValidatorMetaData> list = new ArrayList<ValidatorMetaData>();

        for ( AnnotationData annotationData : annotations ) {
            ValidatorMetaData validatorMetaData = convertAnnotationDataToValidatorMetaData( annotationData );
            list.add( validatorMetaData );
        }

        return list;
    }

Extract meta-data from the annotationData we collected thus far.

@param annotations The annotationData (preprocessed annotation).
@return list of validation meta data.

Extract meta - data from the annotationData we collected thus far .


private ValidatorMetaData convertAnnotationDataToValidatorMetaData(
            AnnotationData annotationData ) {

        ValidatorMetaData metaData = new ValidatorMetaData();
        metaData.setName( annotationData.getName() );

        metaData.setProperties( annotationData.getValues() );

        return metaData;
    }

Converts an AnnotationData into a ValidatorMetaData POJO.

@param annotationData annotationData
@return validator meta data
<p/>
TODO
@NeedsRefactoring("This method shows we are calling annotationData.getValues a lot. " +
"Therefore, we must cache the results of getValues as the annoationData is static " +
"per property per class. ")

Converts an AnnotationData into a ValidatorMetaData POJO .


public static String[]  split( final String string,
                                  final char split, final int limit ) {

        char[][] comps = CharScanner.split( FastStringUtils.toCharArray( string ), split, limit );

        return Str.fromCharArrayOfArrayToStringArray( comps );

    }

public static String [ ] split ( final String string , final char split , final int limit ) { char [ ] [ ] comps = CharScanner . split ( FastStringUtils . toCharArray ( string ) , split , limit ) ; return Str . fromCharArrayOfArrayToStringArray ( comps ) ; }

Splits a string into many parts
@param string input string
@param split char to split by
@param limit the limit of the times you want it split up
@return the split string


public static String[] splitByWhiteSpace( final String string
                                         ) {

        char[][] comps = CharScanner.splitByChars( FastStringUtils.toCharArray( string ), WHITE_SPACE );

        return Str.fromCharArrayOfArrayToStringArray( comps );

    }

public static String [ ] splitByWhiteSpace ( final String string ) { char [ ] [ ] comps = CharScanner . splitByChars ( FastStringUtils . toCharArray ( string ) , WHITE_SPACE ) ; return Str . fromCharArrayOfArrayToStringArray ( comps ) ; }

Split string by white space
@param string string to split
@return the split up string


public static String[] splitByDelimiters( final String string,
                                              final String delimiters ) {

        char[][] comps = CharScanner.splitByChars( FastStringUtils.toCharArray( string ), delimiters.toCharArray() );

        return Str.fromCharArrayOfArrayToStringArray( comps );

    }

public static String [ ] splitByDelimiters ( final String string , final String delimiters ) { char [ ] [ ] comps = CharScanner . splitByChars ( FastStringUtils . toCharArray ( string ) , delimiters . toCharArray ( ) ) ; return Str . fromCharArrayOfArrayToStringArray ( comps ) ; }

Split string by a list of delimiters
@param string string to split
@param delimiters delimeters to split it by
@return the split up string


public static String removeChars( final String string, final char... delimiters ) {
        char[][] comps = CharScanner.splitByCharsNoneEmpty( FastStringUtils.toCharArray( string ), delimiters );
        return new String(Chr.add ( comps ));
    }

public static String removeChars ( final String string , final char ... delimiters ) { char [ ] [ ] comps = CharScanner . splitByCharsNoneEmpty ( FastStringUtils . toCharArray ( string ) , delimiters ) ; return new String ( Chr . add ( comps ) ) ; }

remove chars from a string
@param string string to split
@param delimiters delimeters to remove
@return the split up string


public static String[] splitByCharsNoneEmpty( final String string, int start, int end, final char... delimiters ) {
        Exceptions.requireNonNull( string );

        char[][] comps = CharScanner.splitByCharsNoneEmpty( FastStringUtils.toCharArray( string ), start, end, delimiters );
        return Str.fromCharArrayOfArrayToStringArray( comps );
    }

public static String [ ] splitByCharsNoneEmpty ( final String string , int start , int end , final char ... delimiters ) { Exceptions . requireNonNull ( string ) ; char [ ] [ ] comps = CharScanner . splitByCharsNoneEmpty ( FastStringUtils . toCharArray ( string ) , start , end , delimiters ) ; return Str . fromCharArrayOfArrayToStringArray ( comps ) ; }

Split string by a list of delimiters but none are empty within a range
@param string string to split
@param delimiters delimeters to split it by
@return the split up string


public static double parseDouble( String buffer, int from, int to ) {
        return CharScanner.parseDouble( FastStringUtils.toCharArray(buffer), from , to );
    }

public static double parseDouble ( String buffer , int from , int to ) { return CharScanner . parseDouble ( FastStringUtils . toCharArray ( buffer ) , from , to ) ; }

parse a double
@param buffer input string
@return value


public static int parseInt( String buffer, int from, int to ) {
        return CharScanner.parseInt( FastStringUtils.toCharArray(buffer), from , to );
    }

public static int parseInt ( String buffer , int from , int to ) { return CharScanner . parseInt ( FastStringUtils . toCharArray ( buffer ) , from , to ) ; }

parse an int within a range
@param buffer input string
@return value


public static long parseLong( String buffer, int from, int to ) {
        return CharScanner.parseLong( FastStringUtils.toCharArray(buffer), from , to );
    }

public static long parseLong ( String buffer , int from , int to ) { return CharScanner . parseLong ( FastStringUtils . toCharArray ( buffer ) , from , to ) ; }

parse an long within a range
@param buffer input string
@return value


public static Object getPropByPath( Object item, String... path ) {

        Object o = item;
        for ( int index = 0; index < path.length; index++ ) {
            String propName = path[ index ];
            if ( o == null ) {
                return null;
            } else if ( o.getClass().isArray() || o instanceof Collection ) {

                o = getCollectionProp(o, propName, index, path);
                break;
            } else {
                o = getProp( o, propName );
            }
        }

        return Conversions.unifyListOrArray(o);
    }

public static Object getPropByPath ( Object item , String ... path ) { Object o = item ; for ( int index = 0 ; index < path . length ; index ++ ) { String propName = path [ index ] ; if ( o == null ) { return null ; } else if ( o . getClass ( ) . isArray ( ) || o instanceof Collection ) { o = getCollectionProp ( o , propName , index , path ) ; break ; } else { o = getProp ( o , propName ) ; } } return Conversions . unifyListOrArray ( o ) ; }

This method handles walking lists of lists.

@param item
@param path
@return

This method handles walking lists of lists .


public static Map<String, FieldAccess> getFieldsFromObject( Object object ) {

        try {
           Map<String, FieldAccess> fields;

            if ( object instanceof Map ) {

                fields = getFieldsFromMap( ( Map<String, Object> ) object );
            } else {
                fields = getPropertyFieldAccessMap( object.getClass() );

            }

           return fields;
        } catch (Exception ex) {
           requireNonNull(object, "Item cannot be null" );
           return handle(Map.class, ex, "Unable to get fields from object", className(object));
        }

    }

public
static
Map
<
String
,
FieldAccess
>
getFieldsFromObject
(
Object
object
)
{
try
{
Map
<
String
,
FieldAccess
>
fields
;
if
(
object
instanceof
Map
)
{
fields
=
getFieldsFromMap
(
(
Map
<
String
,
Object
>
)
object
)
;
}
else
{
fields
=
getPropertyFieldAccessMap
(
object
.
getClass
(
)
)
;
}
return
fields
;
}
catch
(
Exception
ex
)
{
requireNonNull
(
object
,
"Item cannot be null"
)
;
return
handle
(
Map
.
class
,
ex
,
"Unable to get fields from object"
,
className
(
object
)
)
;
}
}

Get fields from object or Map.
Allows maps to act like they have fields.

@param object
@return

Get fields from object or Map . Allows maps to act like they have fields .


public static Class<?> getPropertyType( final Object root, final String property ) {

        Map<String, FieldAccess> fields = getPropertyFieldAccessMap( root.getClass() );

        FieldAccess field = fields.get( property );
        return field.type();
    }

public static Class < ? > getPropertyType ( final Object root , final String property ) { Map < String , FieldAccess > fields = getPropertyFieldAccessMap ( root . getClass ( ) ) ; FieldAccess field = fields . get ( property ) ; return field . type ( ) ; }

Get property value, loads nested properties

@param root
@param property
@return

Get property value loads nested properties


public static void injectIntoProperty( Object object, String path, Object value ) {

        String[] properties = propertyPathAsStringArray(path);

        setPropertyValue( object, value, properties );
    }

public static void injectIntoProperty ( Object object , String path , Object value ) { String [ ] properties = propertyPathAsStringArray ( path ) ; setPropertyValue ( object , value , properties ) ; }

Set property value to simulate dependency injection.

@param object
@param path   in dotted notation
@return

Set property value to simulate dependency injection .


public static void idx( Class<?> cls, String path, Object value ) {

        String[] properties = propertyPathAsStringArray(path);

        setPropertyValue( cls, value, properties );
    }

public static void idx ( Class < ? > cls , String path , Object value ) { String [ ] properties = propertyPathAsStringArray ( path ) ; setPropertyValue ( cls , value , properties ) ; }

Set a static value

@param cls
@param path   in dotted notation
@return


private static Object getCollectionProp(Object o, String propName, int index, String[] path
                                           ) {
        o = _getFieldValuesFromCollectionOrArray(o, propName);

        if ( index + 1 == path.length ) {
            return o;
        } else {
            index++;
            return getCollectionProp(o, path[index], index, path);
        }
    }

private static Object getCollectionProp ( Object o , String propName , int index , String [ ] path ) { o = _getFieldValuesFromCollectionOrArray ( o , propName ) ; if ( index + 1 == path . length ) { return o ; } else { index ++ ; return getCollectionProp ( o , path [ index ] , index , path ) ; } }

This is an amazing little recursive method. It walks a fanout of
nested collection to pull out the leaf nodes

This is an amazing little recursive method . It walks a fanout of nested collection to pull out the leaf nodes


public static Object getProp( Object object, final String property ) {
        if ( object == null ) {
            return null;
        }

        if ( isDigits( property ) ) {
                /* We can index numbers and names. */
            object = idx(object, StringScanner.parseInt(property));

        }

        Class<?> cls = object.getClass();

        /** Tries the getters first. */
        Map<String, FieldAccess> fields = Reflection.getPropertyFieldAccessors( cls );

        if ( !fields.containsKey( property ) ) {
            fields = Reflection.getAllAccessorFields( cls );
        }

        if ( !fields.containsKey( property ) ) {
            return null;
        } else {
            return fields.get( property ).getValue( object );
        }

    }

public
static
Object
getProp
(
Object
object
,
final
String
property
)
{
if
(
object
==
)
{
return
;
}
if
(
isDigits
(
property
)
)
{
/* We can index numbers and names. */
object
=
idx
(
object
,
StringScanner
.
parseInt
(
property
)
)
;
}
Class
<
>
cls
=
object
.
getClass
(
)
;
/** Tries the getters first. */
Map
<
String
,
FieldAccess
>
fields
=
Reflection
.
getPropertyFieldAccessors
(
cls
)
;
if
(
!
fields
.
containsKey
(
property
)
)
{
fields
=
Reflection
.
getAllAccessorFields
(
cls
)
;
}
if
(
!
fields
.
containsKey
(
property
)
)
{
return
;
}
else
{
return
fields
.
get
(
property
)
.
getValue
(
object
)
;
}
}

This is one is forgiving of null paths.
This works with getters first, i.e., properties.

@param object
@param property
@return

This is one is forgiving of null paths . This works with getters first i . e . properties .


public static int getPropertyInt( final Object root, final String... properties ) {

        final String lastProperty = properties[ properties.length - 1 ];

        if ( isDigits( lastProperty ) ) {

            return Conversions.toInt(getPropertyValue(root, properties));

        }

        Object object = baseForGetProperty( root, properties );

        Map<String, FieldAccess> fields = getFieldsFromObject( object );

        FieldAccess field = fields.get( lastProperty );

        if ( field.type() == Typ.intgr ) {
            return field.getInt( object );
        } else {
            return Conversions.toInt( field.getValue( object ) );
        }

    }

public static int getPropertyInt ( final Object root , final String ... properties ) { final String lastProperty = properties [ properties . length - 1 ] ; if ( isDigits ( lastProperty ) ) { return Conversions . toInt ( getPropertyValue ( root , properties ) ) ; } Object object = baseForGetProperty ( root , properties ) ; Map < String , FieldAccess > fields = getFieldsFromObject ( object ) ; FieldAccess field = fields . get ( lastProperty ) ; if ( field . type ( ) == Typ . intgr ) { return field . getInt ( object ) ; } else { return Conversions . toInt ( field . getValue ( object ) ) ; } }


public void init() {
        /* If the parent and name are equal to null,
         * use the classname to load listFromClassLoader.
    	 * */
        if ( name == null && parent == null ) {
            this.setDetailMessage( "{" + this.getClass().getName() + DETAIL_KEY + "}" );
            this.setSummaryMessage( "{" + this.getClass().getName() + SUMMARY_KEY + "}" );
        /* If the parent is null and the name is not,
         * use the name to load listFromClassLoader.
         */
        } else if ( name != null && parent == null ) {
            this.setDetailMessage( "{" + "message." + getName() + DETAIL_KEY + "}" );
            this.setSummaryMessage( "{" + "message." + getName() + SUMMARY_KEY + "}" );
        /* If the parent is present, initialize the message keys
         * with the parent name.
         */
        } else if ( parent != null ) {
            this.setDetailMessage( "{" + "message." + parent + DETAIL_KEY + "}" );
            this.setSummaryMessage( "{" + "message." + parent + SUMMARY_KEY + "}" );
        }
    }

The init method tries to generate the message keys.
You should only call the init method if you don't inject
values into the detailMessage and summaryMessage.

The init method tries to generate the message keys . You should only call the init method if you don t inject values into the detailMessage and summaryMessage .


public String createMessage( String key, List<String> argKeys, Object... args ) {
        /* Look up the message. */
        String message = getMessage( key );

    	/* Holds the actual arguments. */
        Object[] actualArgs;

    	/* If they passed arguments,
         * then use this as the actual arguments. */
        if ( args.length > 0 ) {
            actualArgs = args;
        /* If they did not pass arguments, use the configured ones. */
        } else if ( argKeys != null ) {
    		/* Convert the keys to values. */
            actualArgs = keysToValues( argKeys );
        } else {
            actualArgs = new Object[]{ };
        }

        return doCreateMessage( message, actualArgs );

    }

Creates a message.

@param argKeys arguments to lookupWithDefault that were configured.
@param args    Arguments that were passed via the object that wants to
generate the message


@SuppressWarnings ( "unchecked" )
    private String doCreateMessage( String message, Object[] actualArgs ) {

        return ValidationContext.get().createMessage( message, getSubject(), actualArgs );
    }

@ SuppressWarnings ( "unchecked" ) private String doCreateMessage ( String message , Object [ ] actualArgs ) { return ValidationContext . get ( ) . createMessage ( message , getSubject ( ) , actualArgs ) ; }

Actually creates the message.

@param message    The message that was looked up.
@param actualArgs Arguments to the message.
@return


private Object[] keysToValues( List<String> argKeys ) {
        List<String> values = new ArrayList<>();
        for ( String key : argKeys ) {
            values.add( getMessage( key ) );
        }
        return values.toArray();
    }

private Object [ ] keysToValues ( List < String > argKeys ) { List < String > values = new ArrayList <> ( ) ; for ( String key : argKeys ) { values . add ( getMessage ( key ) ) ; } return values . toArray ( ) ; }


public String getSubject() {
        return ValidationContext.get().getCurrentSubject() == null ? this.subject :
                ValidationContext.get().getCurrentSubject();
    }

public String getSubject ( ) { return ValidationContext . get ( ) . getCurrentSubject ( ) == null ? this . subject : ValidationContext . get ( ) . getCurrentSubject ( ) ; }

Gets the current subject or the configured subject if the
current subject is not found.

Gets the current subject or the configured subject if the current subject is not found .


public Object parseText(String text) {
        if (text == null || text.length() == 0) {
            throw new IllegalArgumentException("The JSON input text should neither be null nor empty.");
        }

        return JsonFactory.create().fromJson ( text );
    }

Parse a text representation of a JSON data structure

@param text JSON text to parse
@return a data structure of lists and maps


private void sendHttpRequest(final Request request, final org.boon.core.Handler<Response> responseHandler) {

        final HttpClientRequest httpClientRequest = httpClient.request(request.getMethod(), request.uri(),
                handleResponse(request, responseHandler));

        final Runnable runnable = new Runnable() {
            @Override
            public void run() {

                if (!request.getMethod().equals("GET")) {
                    httpClientRequest.putHeader("Content-Type", "application/x-www-form-urlencoded").end(request.paramBody());
                } else {
                    httpClientRequest.end();
                }

            }
        };

        if (closed.get()) {
            this.scheduledExecutorService.schedule(new Runnable() {
                @Override
                public void run() {
                    connect();
                    int retry = 0;
                    while (closed.get()) {
                        Sys.sleep(1000);

                        if (!closed.get()) {
                            break;
                        }
                        retry++;
                        if (retry>10) {
                            break;
                        }

                        if ( retry % 3 == 0 ) {
                            connect();
                        }
                    }

                    if (!closed.get()) {
                        runnable.run();
                    } else {
                        responseHandler.handle(new Response("TIMEOUT", -1, new Error(-1, "Timeout", "Timeout", -1L)));
                    }
                }
            }, 10, TimeUnit.MILLISECONDS);
        } else {
            runnable.run();
        }

    }

private void sendHttpRequest ( final Request request , final org . boon . core . Handler < Response > responseHandler ) { final HttpClientRequest httpClientRequest = httpClient . request ( request . getMethod ( ) , request . uri ( ) , handleResponse ( request , responseHandler ) ) ; final Runnable runnable = new Runnable ( ) { @ Override public void run ( ) { if ( ! request . getMethod ( ) . equals ( "GET" ) ) { httpClientRequest . putHeader ( "Content-Type" , "application/x-www-form-urlencoded" ) . end ( request . paramBody ( ) ) ; } else { httpClientRequest . end ( ) ; } } } ; if ( closed . get ( ) ) { this . scheduledExecutorService . schedule ( new Runnable ( ) { @ Override public void run ( ) { connect ( ) ; int retry = 0 ; while ( closed . get ( ) ) { Sys . sleep ( 1000 ) ; if ( ! closed . get ( ) ) { break ; } retry ++ ; if ( retry > 10 ) { break ; } if ( retry % 3 == 0 ) { connect ( ) ; } } if ( ! closed . get ( ) ) { runnable . run ( ) ; } else { responseHandler . handle ( new Response ( "TIMEOUT" , - 1 , new Error ( - 1 , "Timeout" , "Timeout" , - 1L ) ) ) ; } } } , 10 , TimeUnit . MILLISECONDS ) ; } else { runnable . run ( ) ; } }

This actually sends the request.
@param request request
@param responseHandler handler


public void deleteDB(String dbName, String confirm) {
		assertNotEmpty(dbName, "dbName");
		if(!"delete database".equals(confirm))
			throw new IllegalArgumentException("Invalid confirm!");
		dbc.delete(buildUri(dbc.getBaseUri()).path(dbName).build());
	}

public
void
deleteDB
(
String
dbName
,
String
confirm
)
{
assertNotEmpty
(
dbName
,
"dbName"
)
;
if
(
!
"delete database"
.
equals
(
confirm
)
)
throw
new
IllegalArgumentException
(
"Invalid confirm!"
)
;
dbc
.
delete
(
buildUri
(
dbc
.
getBaseUri
(
)
)
.
path
(
dbName
)
.
build
(
)
)
;
}

Requests CouchDB deletes a database.
@param dbName The database name
@param confirm A confirmation string with the value: <tt>delete database</tt>


public void createDB(String dbName) {
		assertNotEmpty(dbName, "dbName");
		InputStream getresp = null;
		HttpResponse putresp = null;
		final URI uri = buildUri(dbc.getBaseUri()).path(dbName).build();
		try {
			getresp = dbc.get(uri);
		} catch (NoDocumentException e) { // db doesn't exist
			final HttpPut put = new HttpPut(uri);
			putresp = dbc.executeRequest(put);
			log.info(String.format("Created Database: '%s'", dbName));
		} finally {
			close(getresp);
			close(putresp);
		}
	}

public
void
createDB
(
String
dbName
)
{
assertNotEmpty
(
dbName
,
"dbName"
)
;
InputStream
getresp
=
;
HttpResponse
putresp
=
;
final
URI
uri
=
buildUri
(
dbc
.
getBaseUri
(
)
)
.
path
(
dbName
)
.
build
(
)
;
try
{
getresp
=
dbc
.
get
(
uri
)
;
}
catch
(
NoDocumentException
e
)
{
// db doesn't exist
final
HttpPut
put
=
new
HttpPut
(
uri
)
;
putresp
=
dbc
.
executeRequest
(
put
)
;
log
.
info
(
String
.
format
(
"Created Database: '%s'"
,
dbName
)
)
;
}
finally
{
close
(
getresp
)
;
close
(
putresp
)
;
}
}

Requests CouchDB creates a new database; if one doesn't exist.
@param dbName The Database name

Requests CouchDB creates a new database ; if one doesn t exist .


public List<String> uuids(long count) {
		final String uri = String.format("%s_uuids?count=%d", dbc.getBaseUri(), count);
		final JsonObject json = dbc.findAny(JsonObject.class, uri);
		return dbc.getGson().fromJson(json.get("uuids").toString(), new TypeToken<List<String>>(){}.getType());
	}

public List < String > uuids ( long count ) { final String uri = String . format ( "%s_uuids?count=%d" , dbc . getBaseUri ( ) , count ) ; final JsonObject json = dbc . findAny ( JsonObject . class , uri ) ; return dbc . getGson ( ) . fromJson ( json . get ( "uuids" ) . toString ( ) , new TypeToken < List < String > > ( ) { } . getType ( ) ) ; }

Request a database sends a list of UUIDs.
@param count The count of UUIDs.
@return a list of UUIDs

Request a database sends a list of UUIDs .


public static List<String> listResources(String path)  {
		try {
			Class<CouchDbUtil> clazz = CouchDbUtil.class;
			URL dirURL = clazz.getClassLoader().getResource(path);
			if (dirURL != null && dirURL.getProtocol().equals("file")) {
				return Arrays.asList(new File(dirURL.toURI()).list());
			}
			if (dirURL != null && dirURL.getProtocol().equals("jar")) {
				String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!"));
				JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));
				Enumeration<JarEntry> entries = jar.entries();
				Set<String> result = new HashSet<String>();
				while(entries.hasMoreElements()) {
					String name = entries.nextElement().getName();
					if (name.startsWith(SPRING_BOOT_DIR)) {
						name = name.substring(SPRING_BOOT_DIR.length());
					}
					if (name.startsWith(path)) {
						String entry = name.substring(path.length());
						int checkSubdir = entry.indexOf("/");
						if (checkSubdir >= 0) {
							entry = entry.substring(0, checkSubdir);
						}
						if(entry.length() > 0) {
							result.add(entry);
						}
					}
				}
				close(jar);
				return new ArrayList<String>(result);
			}
			return null;
		} catch (Exception e) {
			throw new CouchDbException(e);
		}
	}

public static List < String > listResources ( String path ) { try { Class < CouchDbUtil > clazz = CouchDbUtil . class ; URL dirURL = clazz . getClassLoader ( ) . getResource ( path ) ; if ( dirURL != null && dirURL . getProtocol ( ) . equals ( "file" ) ) { return Arrays . asList ( new File ( dirURL . toURI ( ) ) . list ( ) ) ; } if ( dirURL != null && dirURL . getProtocol ( ) . equals ( "jar" ) ) { String jarPath = dirURL . getPath ( ) . substring ( 5 , dirURL . getPath ( ) . indexOf ( "!" ) ) ; JarFile jar = new JarFile ( URLDecoder . decode ( jarPath , "UTF-8" ) ) ; Enumeration < JarEntry > entries = jar . entries ( ) ; Set < String > result = new HashSet < String > ( ) ; while ( entries . hasMoreElements ( ) ) { String name = entries . nextElement ( ) . getName ( ) ; if ( name . startsWith ( SPRING_BOOT_DIR ) ) { name = name . substring ( SPRING_BOOT_DIR . length ( ) ) ; } if ( name . startsWith ( path ) ) { String entry = name . substring ( path . length ( ) ) ; int checkSubdir = entry . indexOf ( "/" ) ; if ( checkSubdir >= 0 ) { entry = entry . substring ( 0 , checkSubdir ) ; } if ( entry . length ( ) > 0 ) { result . add ( entry ) ; } } } close ( jar ) ; return new ArrayList < String > ( result ) ; } return null ; } catch ( Exception e ) { throw new CouchDbException ( e ) ; } }

List directory contents for a resource folder. Not recursive.
This is basically a brute-force implementation.
Works for regular files and also JARs.

@author Greg Briggs
@param path Should end with "/", but not start with one.
@return Just the name of each member item, not the full paths.

List directory contents for a resource folder . Not recursive . This is basically a brute - force implementation . Works for regular files and also JARs .


public ReplicationResult trigger() {
		assertNotEmpty(source, "Source");
		assertNotEmpty(target, "Target");
		HttpResponse response = null;
		try {
			JsonObject json = createJson();
			if(log.isDebugEnabled()) {
				log.debug(json);
			}
			final URI uri = buildUri(dbc.getBaseUri()).path("_replicate").build();
			response = dbc.post(uri, json.toString());
			final InputStreamReader reader = new InputStreamReader(getStream(response), Charsets.UTF_8);
			return dbc.getGson().fromJson(reader, ReplicationResult.class);
		} finally {
			close(response);
		}
	}

public ReplicationResult trigger ( ) { assertNotEmpty ( source , "Source" ) ; assertNotEmpty ( target , "Target" ) ; HttpResponse response = null ; try { JsonObject json = createJson ( ) ; if ( log . isDebugEnabled ( ) ) { log . debug ( json ) ; } final URI uri = buildUri ( dbc . getBaseUri ( ) ) . path ( "_replicate" ) . build ( ) ; response = dbc . post ( uri , json . toString ( ) ) ; final InputStreamReader reader = new InputStreamReader ( getStream ( response ) , Charsets . UTF_8 ) ; return dbc . getGson ( ) . fromJson ( reader , ReplicationResult . class ) ; } finally { close ( response ) ; } }

Triggers a replication request.
@return {@link ReplicationResult}


private <V> V queryValue(Class<V> classOfV) {
		InputStream instream = null;
		try {
			Reader reader = new InputStreamReader(instream = queryForStream(), Charsets.UTF_8);
			JsonArray array = new JsonParser().parse(reader).
							getAsJsonObject().get("rows").getAsJsonArray();
			if(array.size() != 1) {
				throw new NoDocumentException("Expecting a single result but was: " + array.size());
			}
			return JsonToObject(gson, array.get(0), "value", classOfV);
		} finally {
			close(instream);
		}
	}

private
<
V
>
V
queryValue
(
Class
<
V
>
classOfV
)
{
InputStream
instream
=
;
try
{
Reader
reader
=
new
InputStreamReader
(
instream
=
queryForStream
(
)
,
Charsets
.
UTF_8
)
;
JsonArray
array
=
new
JsonParser
(
)
.
parse
(
reader
)
.
getAsJsonObject
(
)
.
get
(
"rows"
)
.
getAsJsonArray
(
)
;
if
(
array
.
size
(
)
!=
1
)
{
throw
new
NoDocumentException
(
"Expecting a single result but was: "
+
array
.
size
(
)
)
;
}
return
JsonToObject
(
gson
,
array
.
get
(
0
)
,
"value"
,
classOfV
)
;
}
finally
{
close
(
instream
)
;
}
}

Queries for scalar values. Internal use.

Queries for scalar values . Internal use .


public View descending(Boolean descending) {
		this.descending = Boolean.valueOf(gson.toJson(descending));
		uriBuilder.query("descending", this.descending);
		return this;
	}

public View descending ( Boolean descending ) { this . descending = Boolean . valueOf ( gson . toJson ( descending ) ) ; uriBuilder . query ( "descending" , this . descending ) ; return this ; }

Reverses the reading direction, not the sort order.
@param descending The descending value true | false
@return {@link View}

Reverses the reading direction not the sort order .


public void synchronizeAllWithDb() {
		List<DesignDocument> documents = getAllFromDesk();
		for (DesignDocument dd : documents) {
			synchronizeWithDb(dd);
		}
	}

public void synchronizeAllWithDb ( ) { List < DesignDocument > documents = getAllFromDesk ( ) ; for ( DesignDocument dd : documents ) { synchronizeWithDb ( dd ) ; } }

Synchronize all design documents on desk to the database.
@see #synchronizeWithDb(DesignDocument)
@see CouchDbClient#syncDesignDocsWithDb()

Synchronize all design documents on desk to the database .


public DesignDocument getFromDb(String id) {
		assertNotEmpty(id, "id");
		final URI uri = buildUri(dbc.getDBUri()).path(id).build();
		return dbc.get(uri, DesignDocument.class);
	}

public DesignDocument getFromDb ( String id ) { assertNotEmpty ( id , "id" ) ; final URI uri = buildUri ( dbc . getDBUri ( ) ) . path ( id ) . build ( ) ; return dbc . get ( uri , DesignDocument . class ) ; }

Gets a design document from the database.
@param id The document id
@return {@link DesignDocument}

Gets a design document from the database .


public List<DesignDocument> getAllFromDesk() {
		final List<DesignDocument> designDocsList = new ArrayList<DesignDocument>();
		for (String docName : listResources(format("%s/", DESIGN_DOCS_DIR))) {
			designDocsList.add(getFromDesk(docName));
		}
		return designDocsList;
	}

public List < DesignDocument > getAllFromDesk ( ) { final List < DesignDocument > designDocsList = new ArrayList < DesignDocument > ( ) ; for ( String docName : listResources ( format ( "%s/" , DESIGN_DOCS_DIR ) ) ) { designDocsList . add ( getFromDesk ( docName ) ) ; } return designDocsList ; }

Gets all design documents from desk.
@see #getFromDesk(String)
@return a list of all design documents


public DesignDocument getFromDesk(String id) {
		assertNotEmpty(id, "id");
		final DesignDocument dd = new DesignDocument();
		final String rootPath = format("%s/%s/", DESIGN_DOCS_DIR, id);
		final List<String> elements = listResources(rootPath);
		if(elements == null) {
			throw new IllegalArgumentException("Design docs directory cannot be empty.");
		}
		// Views
		Map<String, MapReduce> views = null;
		if(elements.contains(VIEWS)) {
			views = new HashMap<String, MapReduce>();
			final String viewsPath = format("%s%s/", rootPath, VIEWS);
			for (String viewDirName : listResources(viewsPath)) { // views sub-dirs
				final MapReduce mr = new MapReduce();
				final String viewPath = format("%s%s/", viewsPath, viewDirName);
				final List<String> dirList = listResources(viewPath);
				for (String fileName : dirList) { // view files
					final String def = readFile(format("/%s%s", viewPath, fileName));
					if(MAP_JS.equals(fileName))
						mr.setMap(def);
					else if(REDUCE_JS.equals(fileName))
						mr.setReduce(def);
				} // /foreach view files
				views.put(viewDirName, mr);
			} // /foreach views sub-dirs
		} // /views
		dd.setId(DESIGN_PREFIX + id);
		dd.setLanguage(JAVASCRIPT);
		dd.setViews(views);
		dd.setFilters(populateMap(rootPath, elements, FILTERS));
		dd.setShows(populateMap(rootPath, elements, SHOWS));
		dd.setLists(populateMap(rootPath, elements, LISTS));
		dd.setUpdates(populateMap(rootPath, elements, UPDATES));
		dd.setValidateDocUpdate(readContent(elements, rootPath, VALIDATE_DOC));
		dd.setRewrites(dbc.getGson().fromJson(readContent(elements, rootPath, REWRITES), JsonArray.class));
		dd.setFulltext(dbc.getGson().fromJson(readContent(elements, rootPath, FULLTEXT), JsonObject.class));
		dd.setIndexes(dbc.getGson().fromJson(readContent(elements, rootPath, INDEXES), JsonObject.class));
		return dd;
	}

Gets a design document from desk.
@param id The document id to get.
@return {@link DesignDocument}


public Response save() {
		assertNotEmpty(replicatorDoc.getSource(), "Source");
		assertNotEmpty(replicatorDoc.getTarget(), "Target");
		if(userCtxName != null) {
			UserCtx ctx = replicatorDoc.new UserCtx();
			ctx.setName(userCtxName);
			ctx.setRoles(userCtxRoles);
			replicatorDoc.setUserCtx(ctx);
		}
		return dbc.put(dbURI, replicatorDoc, true);
	}

public Response save ( ) { assertNotEmpty ( replicatorDoc . getSource ( ) , "Source" ) ; assertNotEmpty ( replicatorDoc . getTarget ( ) , "Target" ) ; if ( userCtxName != null ) { UserCtx ctx = replicatorDoc . new UserCtx ( ) ; ctx . setName ( userCtxName ) ; ctx . setRoles ( userCtxRoles ) ; replicatorDoc . setUserCtx ( ctx ) ; } return dbc . put ( dbURI , replicatorDoc , true ) ; }

Adds a new document to the replicator database.
@return {@link Response}

Adds a new document to the replicator database .


public ReplicatorDocument find() {
		assertNotEmpty(replicatorDoc.getId(), "Doc id");
		final URI uri = buildUri(dbURI).path(replicatorDoc.getId()).query("rev", replicatorDoc.getRevision()).build();
		return dbc.get(uri, ReplicatorDocument.class);
	}

public
ReplicatorDocument
find
(
)
{
assertNotEmpty
(
replicatorDoc
.
getId
(
)
,
"Doc id"
)
;
final
URI
uri
=
buildUri
(
dbURI
)
.
path
(
replicatorDoc
.
getId
(
)
)
.
query
(
"rev"
,
replicatorDoc
.
getRevision
(
)
)
.
build
(
)
;
return
dbc
.
get
(
uri
,
ReplicatorDocument
.
class
)
;
}

Finds a document in the replicator database.
@return {@link ReplicatorDocument}

Finds a document in the replicator database .


public List<ReplicatorDocument> findAll() {
		InputStream instream = null;
		try {
			final URI uri = buildUri(dbURI).path("_all_docs").query("include_docs", "true").build();
			final Reader reader = new InputStreamReader(instream = dbc.get(uri), Charsets.UTF_8);
			final JsonArray jsonArray = new JsonParser().parse(reader)
					.getAsJsonObject().getAsJsonArray("rows");
			final List<ReplicatorDocument> list = new ArrayList<ReplicatorDocument>();
			for (JsonElement jsonElem : jsonArray) {
				JsonElement elem = jsonElem.getAsJsonObject().get("doc");
				if(!getAsString(elem.getAsJsonObject(), "_id").startsWith("_design")) { // skip design docs
					ReplicatorDocument rd = dbc.getGson().fromJson(elem, ReplicatorDocument.class);
					list.add(rd);
				}
			}
			return list;
		} finally {
			close(instream);
		}
	}

public
List
<
ReplicatorDocument
>
findAll
(
)
{
InputStream
instream
=
;
try
{
final
URI
uri
=
buildUri
(
dbURI
)
.
path
(
"_all_docs"
)
.
query
(
"include_docs"
,
"true"
)
.
build
(
)
;
final
Reader
reader
=
new
InputStreamReader
(
instream
=
dbc
.
get
(
uri
)
,
Charsets
.
UTF_8
)
;
final
JsonArray
jsonArray
=
new
JsonParser
(
)
.
parse
(
reader
)
.
getAsJsonObject
(
)
.
getAsJsonArray
(
"rows"
)
;
final
List
<
ReplicatorDocument
>
list
=
new
ArrayList
<
ReplicatorDocument
>
(
)
;
for
(
JsonElement
jsonElem
:
jsonArray
)
{
JsonElement
elem
=
jsonElem
.
getAsJsonObject
(
)
.
get
(
"doc"
)
;
if
(
!
getAsString
(
elem
.
getAsJsonObject
(
)
,
"_id"
)
.
startsWith
(
"_design"
)
)
{
// skip design docs
ReplicatorDocument
rd
=
dbc
.
getGson
(
)
.
fromJson
(
elem
,
ReplicatorDocument
.
class
)
;
list
.
add
(
rd
)
;
}
}
return
list
;
}
finally
{
close
(
instream
)
;
}
}

Finds all documents in the replicator database.
@return a list of {@link ReplicatorDocument}

Finds all documents in the replicator database .


public Response remove() {
		assertNotEmpty(replicatorDoc.getId(), "Doc id");
		assertNotEmpty(replicatorDoc.getRevision(), "Doc rev");
		final URI uri = buildUri(dbURI).path(replicatorDoc.getId()).query("rev", replicatorDoc.getRevision()).build();
		return dbc.delete(uri);
	}

public
Response
remove
(
)
{
assertNotEmpty
(
replicatorDoc
.
getId
(
)
,
"Doc id"
)
;
assertNotEmpty
(
replicatorDoc
.
getRevision
(
)
,
"Doc rev"
)
;
final
URI
uri
=
buildUri
(
dbURI
)
.
path
(
replicatorDoc
.
getId
(
)
)
.
query
(
"rev"
,
replicatorDoc
.
getRevision
(
)
)
.
build
(
)
;
return
dbc
.
delete
(
uri
)
;
}

Removes a document from the replicator database.
@return {@link Response}

Removes a document from the replicator database .


public <T> T find(Class<T> classType, String id, Params params) {
		assertNotEmpty(classType, "Class");
		assertNotEmpty(id, "id");
		final URI uri = buildUri(getDBUri()).pathEncoded(id).query(params).build();
		return get(uri, classType);
	}

public < T > T find ( Class < T > classType , String id , Params params ) { assertNotEmpty ( classType , "Class" ) ; assertNotEmpty ( id , "id" ) ; final URI uri = buildUri ( getDBUri ( ) ) . pathEncoded ( id ) . query ( params ) . build ( ) ; return get ( uri , classType ) ; }

Finds an Object of the specified type.
@param <T> Object type.
@param classType The class of type T.
@param id The document id.
@param params Extra parameters to append.
@return An object of type T.
@throws NoDocumentException If the document is not found in the database.


public <T> List<T> findDocs(String jsonQuery, Class<T> classOfT) {
		assertNotEmpty(jsonQuery, "jsonQuery");
		HttpResponse response = null;
		try {
			response = post(buildUri(getDBUri()).path("_find").build(), jsonQuery);
			Reader reader = new InputStreamReader(getStream(response), Charsets.UTF_8);
			JsonArray jsonArray = new JsonParser().parse(reader)
					.getAsJsonObject().getAsJsonArray("docs");
			List<T> list = new ArrayList<T>();
			for (JsonElement jsonElem : jsonArray) {
				JsonElement elem = jsonElem.getAsJsonObject();
				T t = this.gson.fromJson(elem, classOfT);
				list.add(t);
			}
				return list;
		} finally {
			close(response);
		}
	}

public < T > List < T > findDocs ( String jsonQuery , Class < T > classOfT ) { assertNotEmpty ( jsonQuery , "jsonQuery" ) ; HttpResponse response = null ; try { response = post ( buildUri ( getDBUri ( ) ) . path ( "_find" ) . build ( ) , jsonQuery ) ; Reader reader = new InputStreamReader ( getStream ( response ) , Charsets . UTF_8 ) ; JsonArray jsonArray = new JsonParser ( ) . parse ( reader ) . getAsJsonObject ( ) . getAsJsonArray ( "docs" ) ; List < T > list = new ArrayList < T > ( ) ; for ( JsonElement jsonElem : jsonArray ) { JsonElement elem = jsonElem . getAsJsonObject ( ) ; T t = this . gson . fromJson ( elem , classOfT ) ; list . add ( t ) ; } return list ; } finally { close ( response ) ; } }

Find documents using a declarative JSON querying syntax.
@param <T> The class type.
@param jsonQuery The JSON query string.
@param classOfT The class of type T.
@return The result of the query as a {@code List<T> }
@throws CouchDbException If the query failed to execute or the request is invalid.

Find documents using a declarative JSON querying syntax .


public boolean contains(String id) {
		assertNotEmpty(id, "id");
		HttpResponse response = null;
		try {
			response = head(buildUri(getDBUri()).pathEncoded(id).build());
		} catch (NoDocumentException e) {
			return false;
		} finally {
			close(response);
		}
		return true;
	}

public boolean contains ( String id ) { assertNotEmpty ( id , "id" ) ; HttpResponse response = null ; try { response = head ( buildUri ( getDBUri ( ) ) . pathEncoded ( id ) . build ( ) ) ; } catch ( NoDocumentException e ) { return false ; } finally { close ( response ) ; } return true ; }

Checks if a document exist in the database.
@param id The document _id field.
@return true If the document is found, false otherwise.

Checks if a document exist in the database .


public List<Response> bulk(List<?> objects, boolean newEdits) {
		assertNotEmpty(objects, "objects");
		HttpResponse response = null;
		try {
			final String newEditsVal = newEdits ? "\"new_edits\": true, " : "\"new_edits\": false, ";
			final String json = String.format("{%s%s%s}", newEditsVal, "\"docs\": ", getGson().toJson(objects));
			final URI uri = buildUri(getDBUri()).path("_bulk_docs").build();
			response = post(uri, json);
			return getResponseList(response);
		} finally {
			close(response);
		}
	}

public
List
<
Response
>
bulk
(
List
<
>
objects
,
boolean
newEdits
)
{
assertNotEmpty
(
objects
,
"objects"
)
;
HttpResponse
response
=
;
try
{
final
String
newEditsVal
=
newEdits
"\"new_edits\": true, "
:
"\"new_edits\": false, "
;
final
String
json
=
String
.
format
(
"{%s%s%s}"
,
newEditsVal
,
"\"docs\": "
,
getGson
(
)
.
toJson
(
objects
)
)
;
final
URI
uri
=
buildUri
(
getDBUri
(
)
)
.
path
(
"_bulk_docs"
)
.
build
(
)
;
response
=
post
(
uri
,
json
)
;
return
getResponseList
(
response
)
;
}
finally
{
close
(
response
)
;
}
}

Performs bulk documents create and update request.
@param objects The {@link List} of documents objects.
@param newEdits If false, prevents the database from assigning documents new revision IDs.
@return {@code List<Response>} Containing the resulted entries.

Performs bulk documents create and update request .


Response put(URI uri, Object object, boolean newEntity) {
		assertNotEmpty(object, "object");
		HttpResponse response = null;
		try {
			final JsonObject json = getGson().toJsonTree(object).getAsJsonObject();
			String id = getAsString(json, "_id");
			String rev = getAsString(json, "_rev");
			if(newEntity) { // save
				assertNull(rev, "rev");
				id = (id == null) ? generateUUID() : id;
			} else { // update
				assertNotEmpty(id, "id");
				assertNotEmpty(rev, "rev");
			}
			final HttpPut put = new HttpPut(buildUri(uri).pathEncoded(id).build());
			setEntity(put, json.toString());
			response = executeRequest(put);
			return getResponse(response);
		} finally {
			close(response);
		}
	}

Response
put
(
URI
uri
,
Object
object
,
boolean
newEntity
)
{
assertNotEmpty
(
object
,
"object"
)
;
HttpResponse
response
=
;
try
{
final
JsonObject
json
=
getGson
(
)
.
toJsonTree
(
object
)
.
getAsJsonObject
(
)
;
String
id
=
getAsString
(
json
,
"_id"
)
;
String
rev
=
getAsString
(
json
,
"_rev"
)
;
if
(
newEntity
)
{
// save
assertNull
(
rev
,
"rev"
)
;
id
=
(
id
==
)
generateUUID
(
)
:
id
;
}
else
{
// update
assertNotEmpty
(
id
,
"id"
)
;
assertNotEmpty
(
rev
,
"rev"
)
;
}
final
HttpPut
put
=
new
HttpPut
(
buildUri
(
uri
)
.
pathEncoded
(
id
)
.
build
(
)
)
;
setEntity
(
put
,
json
.
toString
(
)
)
;
response
=
executeRequest
(
put
)
;
return
getResponse
(
response
)
;
}
finally
{
close
(
response
)
;
}
}

Performs a HTTP PUT request, saves or updates a document.
@return {@link Response}

Performs a HTTP PUT request saves or updates a document .


Response put(URI uri, InputStream instream, String contentType) {
		HttpResponse response = null;
		try {
			final HttpPut httpPut = new HttpPut(uri);
			final InputStreamEntity entity = new InputStreamEntity(instream, -1);
			entity.setContentType(contentType);
			httpPut.setEntity(entity);
			response = executeRequest(httpPut);
			return getResponse(response);
		} finally {
			close(response);
		}
	}

Response put ( URI uri , InputStream instream , String contentType ) { HttpResponse response = null ; try { final HttpPut httpPut = new HttpPut ( uri ) ; final InputStreamEntity entity = new InputStreamEntity ( instream , - 1 ) ; entity . setContentType ( contentType ) ; httpPut . setEntity ( entity ) ; response = executeRequest ( httpPut ) ; return getResponse ( response ) ; } finally { close ( response ) ; } }

Performs a HTTP PUT request, saves an attachment.
@return {@link Response}

Performs a HTTP PUT request saves an attachment .


HttpResponse post(URI uri, String json) {
		HttpPost post = new HttpPost(uri);
		setEntity(post, json);
		return executeRequest(post);
	}

HttpResponse post ( URI uri , String json ) { HttpPost post = new HttpPost ( uri ) ; setEntity ( post , json ) ; return executeRequest ( post ) ; }

Performs a HTTP POST request.
@return {@link HttpResponse}


Response delete(URI uri) {
		HttpResponse response = null;
		try {
			HttpDelete delete = new HttpDelete(uri);
			response = executeRequest(delete);
			return getResponse(response);
		} finally {
			close(response);
		}
	}

Response delete ( URI uri ) { HttpResponse response = null ; try { HttpDelete delete = new HttpDelete ( uri ) ; response = executeRequest ( delete ) ; return getResponse ( response ) ; } finally { close ( response ) ; } }

Performs a HTTP DELETE request.
@return {@link Response}


void validate(HttpResponse response) throws IOException {
		final int code = response.getStatusLine().getStatusCode();
		if(code == 200 || code == 201 || code == 202) { // success (ok | created | accepted)
			return;
		}
		String reason = response.getStatusLine().getReasonPhrase();
		switch (code) {
		case HttpStatus.SC_NOT_FOUND: {
			throw new NoDocumentException(reason);
		}
		case HttpStatus.SC_CONFLICT: {
			throw new DocumentConflictException(reason);
		}
		default: { // other errors: 400 | 401 | 500 etc.
			throw new CouchDbException(reason += EntityUtils.toString(response.getEntity()));
		}
		}
	}

void
validate
(
HttpResponse
response
)
throws
IOException
{
final
int
code
=
response
.
getStatusLine
(
)
.
getStatusCode
(
)
;
if
(
code
==
200
||
code
==
201
||
code
==
202
)
{
// success (ok | created | accepted)
return
;
}
String
reason
=
response
.
getStatusLine
(
)
.
getReasonPhrase
(
)
;
switch
(
code
)
{
case
HttpStatus
.
SC_NOT_FOUND
:
{
throw
new
NoDocumentException
(
reason
)
;
}
case
HttpStatus
.
SC_CONFLICT
:
{
throw
new
DocumentConflictException
(
reason
)
;
}
default
:
{
// other errors: 400 | 401 | 500 etc.
throw
new
CouchDbException
(
reason
+=
EntityUtils
.
toString
(
response
.
getEntity
(
)
)
)
;
}
}
}

Validates a HTTP response; on error cases logs status and throws relevant exceptions.
@param response The HTTP response.

Validates a HTTP response ; on error cases logs status and throws relevant exceptions .


private void setEntity(HttpEntityEnclosingRequestBase httpRequest, String json) {
		StringEntity entity = new StringEntity(json, "UTF-8");
		entity.setContentType("application/json");
		httpRequest.setEntity(entity);
	}

private void setEntity ( HttpEntityEnclosingRequestBase httpRequest , String json ) { StringEntity entity = new StringEntity ( json , "UTF-8" ) ; entity . setContentType ( "application/json" ) ; httpRequest . setEntity ( entity ) ; }

Sets a JSON String as a request entity.
@param httpRequest The request to set entity.
@param json The JSON String to set.

Sets a JSON String as a request entity .


public void addAttachment(String name, Attachment attachment) {
		if(attachments == null)
			attachments = new HashMap<String, Attachment>();
		attachments.put(name, attachment);
	}

public void addAttachment ( String name , Attachment attachment ) { if ( attachments == null ) attachments = new HashMap < String , Attachment > ( ) ; attachments . put ( name , attachment ) ; }

Adds an in-line document attachment.
@param name The attachment file name
@param attachment The attachment instance


public ChangesResult getChanges() {
		final URI uri = uriBuilder.query("feed", "normal").build();
		return dbc.get(uri, ChangesResult.class);
	}

public ChangesResult getChanges ( ) { final URI uri = uriBuilder . query ( "feed" , "normal" ) . build ( ) ; return dbc . get ( uri , ChangesResult . class ) ; }

Requests Change notifications of feed type normal.
@return {@link ChangesResult}

Requests Change notifications of feed type normal .


private boolean readNextRow() {
		boolean hasNext = false;
		try {
			if(!stop) {
				String row = "";
				do {
					row = getReader().readLine();
				} while(row.length() == 0);

				if(!row.startsWith("{\"last_seq\":")) {
					setNextRow(gson.fromJson(row, Row.class));
					hasNext = true;
				}
			}
		} catch (Exception e) {
			terminate();
			throw new CouchDbException("Error reading continuous stream.", e);
		}
		if(!hasNext)
			terminate();
		return hasNext;
	}

private
boolean
readNextRow
(
)
{
boolean
hasNext
=
false
;
try
{
if
(
!
stop
)
{
String
row
=
""
;
do
{
row
=
getReader
(
)
.
readLine
(
)
;
}
while
(
row
.
length
(
)
==
0
)
;
if
(
!
row
.
startsWith
(
"{\"last_seq\":"
)
)
{
setNextRow
(
gson
.
fromJson
(
row
,
Row
.
class
)
)
;
hasNext
=
true
;
}
}
}
catch
(
Exception
e
)
{
terminate
(
)
;
throw
new
CouchDbException
(
"Error reading continuous stream."
,
e
)
;
}
if
(
!
hasNext
)
terminate
(
)
;
return
hasNext
;
}

Reads and sets the next feed in the stream.

Reads and sets the next feed in the stream .


public String convert(Double theMoney) {
        if (theMoney == null) {
            throw new IllegalArgumentException("theMoney is null");
        }
        Long intPart = theMoney.longValue();
        Long fractPart = Math.round((theMoney - intPart) * NUM100);
        if (currency == Currency.PER1000) {
            fractPart = Math.round((theMoney - intPart) * NUM1000);
        }
        return convert(intPart, fractPart);
    }

public
String
convert
(
Double
theMoney
)
{
if
(
theMoney
==
)
{
throw
new
IllegalArgumentException
(
"theMoney is null"
)
;
}
Long
intPart
=
theMoney
.
longValue
(
)
;
Long
fractPart
=
Math
.
round
(
(
theMoney
intPart
)
*
NUM100
)
;
if
(
currency
==
Currency
.
PER1000
)
{
fractPart
=
Math
.
round
(
(
theMoney
intPart
)
*
NUM1000
)
;
}
return
convert
(
intPart
,
fractPart
)
;
}

Converts double value to the text description.

@param theMoney
the amount of money in format major.minor
@return the string description of money value

Converts double value to the text description .


public void shutdown() {
        try {
            locksExecutor.shutdown();
            locksExecutor.awaitTermination(5, TimeUnit.SECONDS);
            CountDownLatch latch = new CountDownLatch(1);
            activeLocksLock.writeLock().lock();
            Observable.from(activeLocks.entrySet())
                    .map(Map.Entry::getValue)
                    .flatMap(lock -> releaseLock(lock.getName(), lock.getValue())
                            .map(released -> new Lock(lock.getName(), lock.getValue(), lock.getExpiration(), lock
                                    .getRenewalRate(), !released)))
                    .subscribe(
                            lock -> {
                                if (lock.isLocked()) {
                                    logger.infof("Failed to release lock %s", lock.getName());
                                }
                            },
                            t -> {
                                logger.info("There was an error while releasing locks", t);
                                latch.countDown();
                            },
                            latch::countDown
                    );
            latch.await();
            logger.info("Shutdown complete");
        } catch (InterruptedException e) {
            logger.debug("Shutdown was interrupted. Some locks may not have been released but they will still expire.");
        }
    }

Attempt to release any locks on shutdown so that other clients can obtain those locks without having to wait
for them to expire.

Attempt to release any locks on shutdown so that other clients can obtain those locks without having to wait for them to expire .


public static Observable<Void> write(final Observable<byte[]> data, final ServletOutputStream out) {
        return Observable.create(new Observable.OnSubscribe<Void>() {
            @Override
            public void call(Subscriber<? super Void> subscriber) {
                Observable<Void> events = create(out).onBackpressureBuffer();
                Observable<Void> writeobs = Observable.zip(data, events, (b, aVoid) -> {
                    try {
                        out.write(b);
                    } catch (IOException ioe) {
                        Exceptions.propagate(ioe);
                    }
                    return null;
                });
                writeobs.subscribe(subscriber);
            }
        });
    }

public static Observable < Void > write ( final Observable < byte [ ] > data , final ServletOutputStream out ) { return Observable . create ( new Observable . OnSubscribe < Void > ( ) { @ Override public void call ( Subscriber < ? super Void > subscriber ) { Observable < Void > events = create ( out ) . onBackpressureBuffer ( ) ; Observable < Void > writeobs = Observable . zip ( data , events , ( b , aVoid ) -> { try { out . write ( b ) ; } catch ( IOException ioe ) { Exceptions . propagate ( ioe ) ; } return null ; } ) ; writeobs . subscribe ( subscriber ) ; } } ) ; }

Writes the given Observable data to ServletOutputStream.

This method uses Servlet 3.1 non-blocking API callback mechanisms. When the HTTP
request data becomes available to be read, the subscribed {@code Observer}'s
{@link Observer#onNext onNext} method is invoked. Similarly, when all data for the
HTTP request has been read, the subscribed {@code Observer}'s
{@link Observer#onCompleted onCompleted} method is invoked.

Before calling this method, a web application must put the corresponding HTTP request
into asynchronous mode.

@param data
@param out servlet output stream
@return

Writes the given Observable data to ServletOutputStream .


@Override
    public Observable<Void> addTags(Metric<?> metric, Map<String, String> tags) {
        try {
            checkArgument(tags != null, "Missing tags");
            checkArgument(isValidTagMap(tags), "Invalid tags; tag key is required");
        } catch (Exception e) {
            return Observable.error(e);
        }

        return dataAccess.insertIntoMetricsTagsIndex(metric, tags).concatWith(dataAccess.addTags(metric, tags))
                .toList().map(l -> null);
    }

@
Override
public
Observable
<
Void
>
addTags
(
Metric
<
>
metric
,
Map
<
String
,
String
>
tags
)
{
try
{
checkArgument
(
tags
!=
,
"Missing tags"
)
;
checkArgument
(
isValidTagMap
(
tags
)
,
"Invalid tags; tag key is required"
)
;
}
catch
(
Exception
e
)
{
return
Observable
.
error
(
e
)
;
}
return
dataAccess
.
insertIntoMetricsTagsIndex
(
metric
,
tags
)
.
concatWith
(
dataAccess
.
addTags
(
metric
,
tags
)
)
.
toList
(
)
.
map
(
l
->
)
;
}


public void verifyAndCreateTempTables() {
        ZonedDateTime currentBlock = ZonedDateTime.ofInstant(Instant.ofEpochMilli(DateTimeService.now.get().getMillis()), UTC)
                .with(DateTimeService.startOfPreviousEvenHour());

        ZonedDateTime lastStartupBlock = currentBlock.plus(6, ChronoUnit.HOURS);
        verifyAndCreateTempTables(currentBlock, lastStartupBlock).await();
    }

public void verifyAndCreateTempTables ( ) { ZonedDateTime currentBlock = ZonedDateTime . ofInstant ( Instant . ofEpochMilli ( DateTimeService . now . get ( ) . getMillis ( ) ) , UTC ) . with ( DateTimeService . startOfPreviousEvenHour ( ) ) ; ZonedDateTime lastStartupBlock = currentBlock . plus ( 6 , ChronoUnit . HOURS ) ; verifyAndCreateTempTables ( currentBlock , lastStartupBlock ) . await ( ) ; }

Intended to be used at the startup of the MetricsServiceImpl to ensure we have enough tables for processing


public String getNamespaceId(String namespaceName) {
        return namespaces.computeIfAbsent(namespaceName, n -> getProjectId(namespaceName, token));
    }

public String getNamespaceId ( String namespaceName ) { return namespaces . computeIfAbsent ( namespaceName , n -> getProjectId ( namespaceName , token ) ) ; }

Returns the namespace id for a particular namespace name
@param namespaceName The name of the namespace
@return The id of the namespace or null if the namespace does not exist


private boolean isQuery(HttpServerExchange serverExchange) {
        if (serverExchange.getRequestMethod().toString().equalsIgnoreCase("GET") || serverExchange.getRequestMethod().toString().equalsIgnoreCase("HEAD")) {
            // all GET requests are considered queries
            return true;
        } else if (serverExchange.getRequestMethod().toString().equalsIgnoreCase("POST")) {
            // some POST requests may be queries we need to check.
            if (postQuery != null && postQuery.matcher(serverExchange.getRelativePath()).find()) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

Returns if the request is a query request, eg to perform a READ

Returns if the request is a query request eg to perform a READ


private void sendAuthenticationRequest(HttpServerExchange serverExchange, PooledConnection connection) {
        AuthContext context = serverExchange.getAttachment(AUTH_CONTEXT_KEY);
        String verb = getVerb(serverExchange);

        String resource;
        // if we are not dealing with a query
        if (!isQuery(serverExchange)) {
            // is USER_WRITE_ACCESS is disabled, then use the legacy check.
            // Otherwise check using the actual resource (eg 'hawkular-metrics', 'hawkular-alerts', etc)
            if (USER_WRITE_ACCESS.equalsIgnoreCase("true")) {
                resource = RESOURCE;
            } else {
                resource= resourceName;
            }
        } else {
            resource = RESOURCE;
        }

        context.subjectAccessReview = generateSubjectAccessReview(context.tenant, verb, resource);
        ClientRequest request = buildClientRequest(context);
        context.clientRequestStarting();
        connection.sendRequest(request, new RequestReadyCallback(serverExchange, connection));
    }

Executed when a pooled connection is acquired.

Executed when a pooled connection is acquired .


private String getVerb(HttpServerExchange serverExchange) {
        // if its a query type verb, then treat as a GET type call.
        if (isQuery(serverExchange)) {
            return VERBS.get(GET);
        } else {
            String verb = VERBS.get(serverExchange.getRequestMethod());
            if (verb == null) {
                log.debugf("Unhandled http method '%s'. Checking for read access.", serverExchange.getRequestMethod());
                verb = VERBS_DEFAULT;
            }
            return verb;
        }
    }

Determine the verb we should apply based on the HTTP method being requested.

@return the verb to use

Determine the verb we should apply based on the HTTP method being requested .


private String generateSubjectAccessReview(String namespace, String verb, String resource) {
        ObjectNode objectNode = objectMapper.createObjectNode();
        objectNode.put("apiVersion", "v1");
        objectNode.put("kind", KIND);
        objectNode.put("resource", resource);
        objectNode.put("verb", verb);
        objectNode.put("namespace", namespace);
        return objectNode.toString();
    }

private String generateSubjectAccessReview ( String namespace , String verb , String resource ) { ObjectNode objectNode = objectMapper . createObjectNode ( ) ; objectNode . put ( "apiVersion" , "v1" ) ; objectNode . put ( "kind" , KIND ) ; objectNode . put ( "resource" , resource ) ; objectNode . put ( "verb" , verb ) ; objectNode . put ( "namespace" , namespace ) ; return objectNode . toString ( ) ; }

Generates a SubjectAccessReview object used to request if a user has a certain permission or not.

@param namespace the namespace
@param verb      the requested permission

@return JSON text representation of the SubjectAccessReview object

Generates a SubjectAccessReview object used to request if a user has a certain permission or not .


private void onRequestResult(HttpServerExchange serverExchange, PooledConnection connection, boolean allowed) {
        connectionPools.get(serverExchange.getIoThread()).release(connection);
        // Remove attachment early to make it eligible for GC
        AuthContext context = serverExchange.removeAttachment(AUTH_CONTEXT_KEY);
        apiLatency.update(context.getClientResponseTime(), NANOSECONDS);
        authLatency.update(context.getLatency(), NANOSECONDS);
        if (allowed) {
            serverExchange.dispatch(containerHandler);
        } else {
            endExchange(serverExchange, FORBIDDEN);
        }
    }

Called when the Kubernetes master server reponse has been inspected.

Called when the Kubernetes master server reponse has been inspected .


private void onRequestFailure(HttpServerExchange serverExchange, PooledConnection connection, IOException e,
                                  boolean retry) {
        log.debug("Client request failure", e);
        IoUtils.safeClose(connection);
        ConnectionPool connectionPool = connectionPools.get(serverExchange.getIoThread());
        connectionPool.release(connection);
        AuthContext context = serverExchange.getAttachment(AUTH_CONTEXT_KEY);
        if (context.retries < MAX_RETRY && retry) {
            context.retries++;
            PooledConnectionWaiter waiter = createWaiter(serverExchange);
            if (!connectionPool.offer(waiter)) {
                endExchange(serverExchange, INTERNAL_SERVER_ERROR, TOO_MANY_PENDING_REQUESTS);
            }
        } else {
            endExchange(serverExchange, INTERNAL_SERVER_ERROR, CLIENT_REQUEST_FAILURE);
        }
    }

private
void
onRequestFailure
(
HttpServerExchange
serverExchange
,
PooledConnection
connection
,
IOException
e
,
boolean
retry
)
{
log
.
debug
(
"Client request failure"
,
e
)
;
IoUtils
.
safeClose
(
connection
)
;
ConnectionPool
connectionPool
=
connectionPools
.
get
(
serverExchange
.
getIoThread
(
)
)
;
connectionPool
.
release
(
connection
)
;
AuthContext
context
=
serverExchange
.
getAttachment
(
AUTH_CONTEXT_KEY
)
;
if
(
context
.
retries
<
MAX_RETRY
&&
retry
)
{
context
.
retries
++
;
PooledConnectionWaiter
waiter
=
createWaiter
(
serverExchange
)
;
if
(
!
connectionPool
.
offer
(
waiter
)
)
{
endExchange
(
serverExchange
,
INTERNAL_SERVER_ERROR
,
TOO_MANY_PENDING_REQUESTS
)
;
}
}
else
{
endExchange
(
serverExchange
,
INTERNAL_SERVER_ERROR
,
CLIENT_REQUEST_FAILURE
)
;
}
}

Called if an exception occurs at any stage in the process.

Called if an exception occurs at any stage in the process .


public void init(RxSession session) {
        this.session = session;
        findConfigurationGroup = session.getSession()
                .prepare("SELECT name, value FROM sys_config WHERE config_id = ?")
                .setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);

        findConfigurationValue = session.getSession()
                .prepare("SELECT value FROM sys_config WHERE config_id = ? AND name= ?")
                .setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);

        updateConfigurationValue = session.getSession().prepare(
                "INSERT INTO sys_config (config_id, name, value) VALUES (?, ?, ?)")
                .setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);

        deleteConfigurationValue = session.getSession().prepare(
                "DELETE FROM sys_config WHERE config_id =? and name = ?")
                .setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);

        deleteConfiguration = session.getSession().prepare(
                "DELETE FROM sys_config WHERE config_id = ?")
                .setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);
    }

eventually I would like service initialization async.

eventually I would like service initialization async .


public Observable<JobDetails> findScheduledJobs(Date timeSlice, rx.Scheduler scheduler) {
        return session.executeAndFetch(findAllScheduled.bind(), scheduler)
                .filter(filterNullJobs)
                .filter(row -> row.getTimestamp(0).compareTo(timeSlice) <= 0)
                .map(row -> createJobDetails(
                        row.getUUID(1),
                        row.getString(2),
                        row.getString(3),
                        row.getMap(4, String.class, String.class),
                        getTrigger(row.getUDTValue(5)),
                        JobStatus.fromCode(row.getByte(6)),
                        timeSlice))
                .collect(HashMap::new, (Map<UUID, SortedSet<JobDetails>> map, JobDetails details) -> {
                    SortedSet<JobDetails> set = map.get(details.getJobId());
                    if (set == null) {
                        set = new TreeSet<>((JobDetails d1, JobDetails d2) ->
                                Long.compare(d1.getTrigger().getTriggerTime(), d2.getTrigger().getTriggerTime()));
                    }
                    set.add(details);
                    map.put(details.getJobId(), set);
                })
                .flatMap(map -> Observable.from(map.entrySet()))
                .map(entry -> entry.getValue().first());
    }

public Observable < JobDetails > findScheduledJobs ( Date timeSlice , rx . Scheduler scheduler ) { return session . executeAndFetch ( findAllScheduled . bind ( ) , scheduler ) . filter ( filterNullJobs ) . filter ( row -> row . getTimestamp ( 0 ) . compareTo ( timeSlice ) <= 0 ) . map ( row -> createJobDetails ( row . getUUID ( 1 ) , row . getString ( 2 ) , row . getString ( 3 ) , row . getMap ( 4 , String . class , String . class ) , getTrigger ( row . getUDTValue ( 5 ) ) , JobStatus . fromCode ( row . getByte ( 6 ) ) , timeSlice ) ) . collect ( HashMap :: new , ( Map < UUID , SortedSet < JobDetails > > map , JobDetails details ) -> { SortedSet < JobDetails > set = map . get ( details . getJobId ( ) ) ; if ( set == null ) { set = new TreeSet <> ( ( JobDetails d1 , JobDetails d2 ) -> Long . compare ( d1 . getTrigger ( ) . getTriggerTime ( ) , d2 . getTrigger ( ) . getTriggerTime ( ) ) ) ; } set . add ( details ) ; map . put ( details . getJobId ( ) , set ) ; } ) . flatMap ( map -> Observable . from ( map . entrySet ( ) ) ) . map ( entry -> entry . getValue ( ) . first ( ) ) ; }


public static <T extends BucketPoint> List<T> toList(Map<Long, T> pointMap, Buckets buckets, BiFunction<Long,
            Long, T> emptyBucketFactory) {
        List<T> result = new ArrayList<>(buckets.getCount());
        for (int index = 0; index < buckets.getCount(); index++) {
            long from = buckets.getBucketStart(index);
            T bucketPoint = pointMap.get(from);
            if (bucketPoint == null) {
                long to = from + buckets.getStep();
                bucketPoint = emptyBucketFactory.apply(from, to);
            }
            result.add(bucketPoint);
        }
        return result;
    }

public static < T extends BucketPoint > List < T > toList ( Map < Long , T > pointMap , Buckets buckets , BiFunction < Long , Long , T > emptyBucketFactory ) { List < T > result = new ArrayList <> ( buckets . getCount ( ) ) ; for ( int index = 0 ; index < buckets . getCount ( ) ; index ++ ) { long from = buckets . getBucketStart ( index ) ; T bucketPoint = pointMap . get ( from ) ; if ( bucketPoint == null ) { long to = from + buckets . getStep ( ) ; bucketPoint = emptyBucketFactory . apply ( from , to ) ; } result . add ( bucketPoint ) ; } return result ; }

Converts bucket points indexed by start time into a list, ordered by start time. Blanks will be filled with
empty bucket points.

Converts bucket points indexed by start time into a list ordered by start time . Blanks will be filled with empty bucket points .


public static void endExchange(HttpServerExchange exchange, int statusCode, String reasonPhrase) {
        exchange.setStatusCode(statusCode);
        if (reasonPhrase != null) {
            exchange.setReasonPhrase(reasonPhrase);
        }
        exchange.endExchange();
    }

public static void endExchange ( HttpServerExchange exchange , int statusCode , String reasonPhrase ) { exchange . setStatusCode ( statusCode ) ; if ( reasonPhrase != null ) { exchange . setReasonPhrase ( reasonPhrase ) ; } exchange . endExchange ( ) ; }

Changes the status code of the response, sets the HTTP reason phrase and ends the exchange.

@param exchange     the HTTP server request/response exchange
@param statusCode   the HTTP status code
@param reasonPhrase the HTTP status message

@see HttpServerExchange#setStatusCode(int)
@see HttpServerExchange#setReasonPhrase(String)
@see HttpServerExchange#endExchange()

Changes the status code of the response sets the HTTP reason phrase and ends the exchange .


@Override
    public Observable<Observable<Row>> findAllDataFromBucket(long timestamp, int pageSize, int maxConcurrency) {
        PreparedStatement ts =
                getTempStatement(MetricType.UNDEFINED, TempStatement.SCAN_WITH_TOKEN_RANGES, timestamp);

        // The table does not exists - case such as when starting Hawkular-Metrics for the first time just before
        // compression kicks in.
        if(ts == null || prepMap.floorKey(timestamp) == 0L) {
            return Observable.empty();
        }

        return Observable.from(getTokenRanges())
                .map(tr -> rxSession.executeAndFetch(
                        ts
                                .bind()
                                .setToken(0, tr.getStart())
                                .setToken(1, tr.getEnd())
                                .setFetchSize(pageSize)));
    }

Fetch all the data from a temporary table for the compression job. Using TokenRanges avoids fetching first
all the metrics' partition keys and then requesting them.

Performance can be improved by using data locality and fetching with multiple threads.

@param timestamp A timestamp inside the wanted bucket (such as the previous starting row timestamp)
@param pageSize How many rows to fetch each time
@param maxConcurrency To how many streams should token ranges be split to
@return Observable of Observables per partition key

Fetch all the data from a temporary table for the compression job . Using TokenRanges avoids fetching first all the metrics partition keys and then requesting them .


public static Buckets fromStep(long start, long end, long step) {
        checkTimeRange(start, end);
        checkArgument(step > 0, "step is not positive: %s", step);
        if (step > (end - start)) {
            return new Buckets(start, step, 1);
        }
        long quotient = (end - start) / step;
        long remainder = (end - start) % step;
        long count;
        if (remainder == 0) {
            count = quotient;
        } else {
            count = quotient + 1;
        }
        checkArgument(count <= Integer.MAX_VALUE, "Computed number of buckets is too big: %s", count);
        return new Buckets(start, step, (int) count);
    }

Force bucket step.

@param start start time
@param end   end time
@param step  desired step

@return an instance of {@link Buckets}, starting at {@code start}, separated by intervals of size {@code step}


public boolean sendMsg(Message msg) {
        SendResult sendResult = null;
        try {
            sendResult = producer.send(msg);
        } catch (Exception e) {
            logger.error("send msg error", e);
        }
        return sendResult != null && sendResult.getSendStatus() == SendStatus.SEND_OK;
    }

public
boolean
sendMsg
(
Message
msg
)
{
SendResult
sendResult
=
;
try
{
sendResult
=
producer
.
send
(
msg
)
;
}
catch
(
Exception
e
)
{
logger
.
error
(
"send msg error"
,
e
)
;
}
return
sendResult
!=
&&
sendResult
.
getSendStatus
(
)
==
SendStatus
.
SEND_OK
;
}

send msg.

@param msg content
@return send result


public void sendOneWayMsg(Message msg) {
        try {
            producer.sendOneway(msg);
        } catch (Exception e) {
            logger.error("send msg error", e);
        }
    }

public
void
sendOneWayMsg
(
Message
msg
)
{
try
{
producer
.
sendOneway
(
msg
)
;
}
catch
(
Exception
e
)
{
logger
.
error
(
"send msg error"
,
e
)
;
}
}


public boolean sendDelayMsg(String topic, String tag, Message msg, int delayLevel) {
        msg.setDelayTimeLevel(delayLevel);
        SendResult sendResult = null;
        try {
            sendResult = producer.send(msg);
        } catch (Exception e) {
            logger.error("send msg error", e);
        }
        return sendResult != null && sendResult.getSendStatus() == SendStatus.SEND_OK;
    }

public
boolean
sendDelayMsg
(
String
topic
,
String
tag
,
Message
msg
,
int
delayLevel
)
{
msg
.
setDelayTimeLevel
(
delayLevel
)
;
SendResult
sendResult
=
;
try
{
sendResult
=
producer
.
send
(
msg
)
;
}
catch
(
Exception
e
)
{
logger
.
error
(
"send msg error"
,
e
)
;
}
return
sendResult
!=
&&
sendResult
.
getSendStatus
(
)
==
SendStatus
.
SEND_OK
;
}

send delay msg.

@param msg content
@param delayLevel 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
@return send result


@Override
	public ScanResult<String> scan(String cursor, ScanParams params) {
		// We need to extract the MATCH argument from the scan params
		Collection<byte[]> rawParams = params.getParams();

		// Raw collection is a list of byte[], made of: key1, value1, key2, value2, etc.
		boolean isKey = true;
		String match = null;
		boolean foundMatchKey = false;

		// So, we run over the list, where any even index is a key, and the following data is its value.
		for (byte[] raw : rawParams) {
			if (isKey) {
				String key = new String(raw);
				if (key.equals(new String(MATCH.raw))) {
					// What really interests us is the MATCH key.
					foundMatchKey = true;
				}
			}
			// As soon as we've found the MATCH key, we can stop searching.
			else if (foundMatchKey) {
				match = new String(raw);
				break;
			}
			isKey = !isKey;
		}

		// Our simple implementation of SCAN is really a plain wrapper for KEYS,
		// relying on the current mock implementation of the pattern search.
		return new ScanResult<String>("0", new ArrayList<String>(keys(match)));
	}

In this simple proposal, we're not testing complex iterations
of scan cursor. SCAN is simply a wrapper for KEYS, and the result
is given in one single response, no matter the COUNT argument.

In this simple proposal we re not testing complex iterations of scan cursor . SCAN is simply a wrapper for KEYS and the result is given in one single response no matter the COUNT argument .


public void setValue(String property, Value value) {
        this.valueByProperty.put(property.toLowerCase(), value);
    }

public void setValue ( String property , Value value ) { this . valueByProperty . put ( property . toLowerCase ( ) , value ) ; }


public String add(File file, boolean preserveExternalFileName) {
    File existingFile = checkFileExists(file);
    String result = zipPathFor(existingFile, preserveExternalFileName);
    entries.put(existingFile, result);
    return result;
  }

public String add ( File file , boolean preserveExternalFileName ) { File existingFile = checkFileExists ( file ) ; String result = zipPathFor ( existingFile , preserveExternalFileName ) ; entries . put ( existingFile , result ) ; return result ; }

Add a file to the ZIP.
@param file The file to add
@param preserveExternalFileName Whether external file names are to be preserved as much as possible, or whether
they should be replaced with unique numbers
@return The name of the ZIP entry


public void replace(File file, boolean preserveExternalFileName, String text) {
    String path = entries.containsKey(file) ? entries.remove(file) : zipPathFor(file, preserveExternalFileName);
    entries.put(text, path);
  }

public void replace ( File file , boolean preserveExternalFileName , String text ) { String path = entries . containsKey ( file ) ? entries . remove ( file ) : zipPathFor ( file , preserveExternalFileName ) ; entries . put ( text , path ) ; }

Replace the contents of a file with a different text.
@param file The file for which to replace the content
@param preserveExternalFileName Whether external file names are to be preserved as much as possible, or whether
they should be replaced with unique numbers
@param text The new content to include in the ZIP

Replace the contents of a file with a different text .


public File build() throws IOException {
    if (entries.isEmpty()) {
      throw new EmptyZipException();
    }
    String fileName = "import_configuration" + System.currentTimeMillis() + ".zip";
    File result = new File(TEMP_DIR.toFile(), fileName);

    try (ZipOutputStream zip = new ZipOutputStream(
        Files.newOutputStream(result.toPath(), StandardOpenOption.CREATE_NEW))) {
      customization.init(entries.values(), this::streamFor);
      for (Entry<Object, String> entry : entries.entrySet()) {
        try (InputStream input = toInputStream(entry.getKey())) {
          addEntry(ExtraZipEntry.of(entry.getValue(),
              customization.customize(entry.getValue(),  input)), zip);
        }
      }
      customization.extraEntries().forEach(entry -> addEntry(entry, zip));
      zip.closeEntry();
    }

    return result;
  }

public File build ( ) throws IOException { if ( entries . isEmpty ( ) ) { throw new EmptyZipException ( ) ; } String fileName = "import_configuration" + System . currentTimeMillis ( ) + ".zip" ; File result = new File ( TEMP_DIR . toFile ( ) , fileName ) ; try ( ZipOutputStream zip = new ZipOutputStream ( Files . newOutputStream ( result . toPath ( ) , StandardOpenOption . CREATE_NEW ) ) ) { customization . init ( entries . values ( ) , this :: streamFor ) ; for ( Entry < Object , String > entry : entries . entrySet ( ) ) { try ( InputStream input = toInputStream ( entry . getKey ( ) ) ) { addEntry ( ExtraZipEntry . of ( entry . getValue ( ) , customization . customize ( entry . getValue ( ) , input ) ) , zip ) ; } } customization . extraEntries ( ) . forEach ( entry -> addEntry ( entry , zip ) ) ; zip . closeEntry ( ) ; } return result ; }

Build a ZIP file containing the added entries.
@return A ZIP file containing the added entries
@throws IOException In case an I/O error occurs

Build a ZIP file containing the added entries .


public Metrics generate(C component, DataBuffer product) throws IOException {
    return generate(Collections.singletonList(component), product);
  }

public Metrics generate ( C component , DataBuffer product ) throws IOException { return generate ( Collections . singletonList ( component ) , product ) ; }

Generate a product from a single piece.
@param component The component to generate the product from
@param product The output to write the assembled product to
@return Metrics about the generation process
@throws IOException When an I/O error occurs

Generate a product from a single piece .


@Override
  @Deprecated
  public ContentResult fetchContent(String contentId) throws IOException {
    try {
      String contentResource = resourceCache.getCiResourceUri();
      URIBuilder builder = new URIBuilder(contentResource);
      builder.setParameter("cid", contentId);
      URI uri = builder.build();
      return restClient.get(uri.toString(), contentResultFactory);
    } catch (URISyntaxException e) {
      throw new IllegalStateException("Failed to create content resource uri.", e);
    }
  }

Fetch the content for the specified content id.
@param contentId The id of the content to fetch.
@return A ContentResult
@throws IOException When an I/O error occurs
@deprecated Will be removed without replacement in a future version

Fetch the content for the specified content id .