Coverage Report - co.stateful.core.DyCounters
 
Classes in this File Line Coverage Branch Coverage Complexity
DyCounters
0%
0/13
0%
0/10
1.5
DyCounters$1
0%
0/4
N/A
1.5
DyCounters$AjcClosure1
0%
0/1
N/A
1.5
DyCounters$AjcClosure11
0%
0/1
N/A
1.5
DyCounters$AjcClosure3
0%
0/1
N/A
1.5
DyCounters$AjcClosure5
0%
0/1
N/A
1.5
DyCounters$AjcClosure7
0%
0/1
N/A
1.5
DyCounters$AjcClosure9
0%
0/1
N/A
1.5
 
 1  0
 /**
 2  
  * Copyright (c) 2014, stateful.co
 3  
  * All rights reserved.
 4  
  *
 5  
  * Redistribution and use in source and binary forms, with or without
 6  
  * modification, are permitted provided that the following conditions
 7  
  * are met: 1) Redistributions of source code must retain the above
 8  
  * copyright notice, this list of conditions and the following
 9  
  * disclaimer. 2) Redistributions in binary form must reproduce the above
 10  
  * copyright notice, this list of conditions and the following
 11  
  * disclaimer in the documentation and/or other materials provided
 12  
  * with the distribution. 3) Neither the name of the stateful.co nor
 13  
  * the names of its contributors may be used to endorse or promote
 14  
  * products derived from this software without specific prior written
 15  
  * permission.
 16  
  *
 17  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18  
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 19  
  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 20  
  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 21  
  * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 22  
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 23  
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 24  
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 25  
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 26  
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 27  
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 28  
  * OF THE POSSIBILITY OF SUCH DAMAGE.
 29  
  */
 30  
 package co.stateful.core;
 31  
 
 32  
 import co.stateful.spi.Counter;
 33  
 import co.stateful.spi.Counters;
 34  
 import com.amazonaws.services.dynamodbv2.model.AttributeValue;
 35  
 import com.google.common.base.Function;
 36  
 import com.google.common.base.Predicates;
 37  
 import com.google.common.collect.Iterables;
 38  
 import com.google.common.collect.Iterators;
 39  
 import com.jcabi.aspects.Cacheable;
 40  
 import com.jcabi.aspects.Immutable;
 41  
 import com.jcabi.aspects.Loggable;
 42  
 import com.jcabi.dynamo.Attributes;
 43  
 import com.jcabi.dynamo.Conditions;
 44  
 import com.jcabi.dynamo.Item;
 45  
 import com.jcabi.dynamo.QueryValve;
 46  
 import com.jcabi.dynamo.Table;
 47  
 import com.jcabi.urn.URN;
 48  
 import java.io.IOException;
 49  
 import java.util.concurrent.TimeUnit;
 50  
 import lombok.EqualsAndHashCode;
 51  
 import lombok.ToString;
 52  
 
 53  
 /**
 54  
  * Counters in DynamoDB.
 55  
  *
 56  
  * @author Yegor Bugayenko (yegor@tpc2.com)
 57  
  * @version $Id$
 58  
  */
 59  
 @Immutable
 60  0
 @ToString
 61  0
 @EqualsAndHashCode(of = "owner")
 62  
 @Loggable(Loggable.DEBUG)
 63  
 final class DyCounters implements Counters {
 64  
 
 65  
     /**
 66  
      * Table name.
 67  
      */
 68  
     public static final String TBL = "counters";
 69  
 
 70  
     /**
 71  
      * Hash.
 72  
      */
 73  
     public static final String HASH = "urn";
 74  
 
 75  
     /**
 76  
      * Range.
 77  
      */
 78  
     public static final String RANGE = "name";
 79  
 
 80  
     /**
 81  
      * Value attribute.
 82  
      */
 83  
     public static final String ATTR_VALUE = "value";
 84  
 
 85  
     /**
 86  
      * Dynamo table.
 87  
      */
 88  
     private final transient Table table;
 89  
 
 90  
     /**
 91  
      * Name of the user.
 92  
      */
 93  
     private final transient URN owner;
 94  
 
 95  
     /**
 96  
      * Ctor.
 97  
      * @param tbl Dynamo table
 98  
      * @param urn Owner of them
 99  
      */
 100  0
     DyCounters(final Table tbl, final URN urn) {
 101  0
         this.table = tbl;
 102  0
         this.owner = urn;
 103  0
     }
 104  
 
 105  
     @Override
 106  
     @Cacheable.FlushAfter
 107  
     public void create(final String name) throws IOException {
 108  0
         this.table.put(
 109  
             new Attributes()
 110  
                 .with(DyCounters.HASH, this.owner)
 111  
                 .with(DyCounters.RANGE, name)
 112  
                 .with(DyCounters.ATTR_VALUE, new AttributeValue().withN("0"))
 113  
         );
 114  0
     }
 115  
 
 116  
     @Override
 117  
     @Cacheable.FlushAfter
 118  
     public void delete(final String name) {
 119  0
         Iterators.removeIf(
 120  
             this.table.frame()
 121  
                 .through(new QueryValve().withLimit(1))
 122  
                 .where(DyCounters.HASH, Conditions.equalTo(this.owner))
 123  
                 .where(DyCounters.RANGE, Conditions.equalTo(name))
 124  
                 .iterator(),
 125  
             Predicates.alwaysTrue()
 126  
         );
 127  0
     }
 128  
 
 129  
     @Override
 130  
     @Cacheable(lifetime = 1, unit = TimeUnit.HOURS)
 131  
     public Counter get(final String name) {
 132  0
         return new DyCounter(
 133  
             this.table.frame()
 134  
                 .through(new QueryValve().withLimit(1))
 135  
                 .where(DyCounters.HASH, Conditions.equalTo(this.owner))
 136  
                 .where(DyCounters.RANGE, Conditions.equalTo(name))
 137  
                 .iterator()
 138  
                 .next()
 139  
         );
 140  
     }
 141  
 
 142  
     @Override
 143  
     @Cacheable(lifetime = 1, unit = TimeUnit.HOURS)
 144  
     public Iterable<String> names() {
 145  0
         return Iterables.transform(
 146  
             this.table.frame()
 147  
                 .through(new QueryValve())
 148  
                 .where(DyCounters.HASH, Conditions.equalTo(this.owner)),
 149  0
             new Function<Item, String>() {
 150  
                 @Override
 151  
                 public String apply(final Item item) {
 152  
                     try {
 153  0
                         return item.get(DyCounters.RANGE).getS();
 154  0
                     } catch (final IOException ex) {
 155  0
                         throw new IllegalStateException(ex);
 156  
                     }
 157  
                 }
 158  
             }
 159  
         );
 160  
     }
 161  
 }