Skip to content

Commit

Permalink
#22 Usage added
Browse files Browse the repository at this point in the history
  • Loading branch information
Yegor Bugayenko committed Nov 19, 2016
1 parent e88753f commit 8f14bf0
Show file tree
Hide file tree
Showing 20 changed files with 610 additions and 72 deletions.
13 changes: 0 additions & 13 deletions .idea/libraries/Maven__com_jcabi_jcabi_aspects_0_22_3.xml

This file was deleted.

13 changes: 0 additions & 13 deletions .idea/libraries/Maven__commons_io_commons_io_2_4.xml

This file was deleted.

13 changes: 0 additions & 13 deletions .idea/libraries/Maven__org_apache_commons_commons_lang3_3_4.xml

This file was deleted.

18 changes: 14 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<parent>
<groupId>com.jcabi</groupId>
<artifactId>parent</artifactId>
<version>0.43</version>
<version>0.47</version>
</parent>
<groupId>io.jare</groupId>
<artifactId>web</artifactId>
Expand Down Expand Up @@ -144,8 +144,6 @@
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-xml</artifactId>
<version>0.17.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.jcabi</groupId>
Expand All @@ -164,7 +162,8 @@
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-dynamo</artifactId>
<version>0.21.2</version>
<version>1.0-SNAPSHOT</version>
<!-- <version>0.21.2</version> -->
</dependency>
<dependency>
<groupId>com.jcabi</groupId>
Expand Down Expand Up @@ -201,6 +200,17 @@
<classifier>dom</classifier>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-jdbc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.193</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>findbugs-annotations</artifactId>
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/io/jare/cached/CdDomain.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import com.jcabi.aspects.Cacheable;
import io.jare.model.Domain;
import io.jare.model.Usage;
import java.io.IOException;

/**
Expand All @@ -33,7 +34,7 @@
* @version $Id$
* @since 1.0
*/
public final class CdDomain implements Domain {
final class CdDomain implements Domain {

/**
* Original.
Expand All @@ -44,7 +45,7 @@ public final class CdDomain implements Domain {
* Ctor.
* @param domain Original
*/
public CdDomain(final Domain domain) {
CdDomain(final Domain domain) {
this.origin = domain;
}

Expand All @@ -64,4 +65,9 @@ public String name() throws IOException {
public void delete() throws IOException {
this.origin.delete();
}

@Override
public Usage usage() throws IOException {
return new CdUsage(this.usage());
}
}
71 changes: 71 additions & 0 deletions src/main/java/io/jare/cached/CdUsage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 jare.io
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions: the above copyright notice and this
* permission notice shall be included in all copies or substantial
* portions of the Software. The software is provided "as is", without
* warranty of any kind, express or implied, including but not limited to
* the warranties of merchantability, fitness for a particular purpose
* and non-infringement. In no event shall the authors or copyright
* holders be liable for any claim, damages or other liability, whether
* in an action of contract, tort or otherwise, arising from, out of or
* in connection with the software or the use or other dealings in the
* software.
*/
package io.jare.cached;

import com.jcabi.aspects.Cacheable;
import io.jare.model.Usage;
import java.io.IOException;
import java.util.Date;
import java.util.SortedMap;
import java.util.concurrent.TimeUnit;

/**
* Cached Usage.
*
* @author Yegor Bugayenko (yegor@teamed.io)
* @version $Id$
* @since 0.7
*/
final class CdUsage implements Usage {

/**
* Original.
*/
private final transient Usage origin;

/**
* Ctor.
* @param usage Original
*/
CdUsage(final Usage usage) {
this.origin = usage;
}

@Override
@Cacheable.FlushBefore
public void add(final Date date, final long bytes) throws IOException {
this.origin.add(date, bytes);
}

@Override
@Cacheable(lifetime = 1, unit = TimeUnit.HOURS)
public long total() throws IOException {
return this.origin.total();
}

@Override
@Cacheable(lifetime = 1, unit = TimeUnit.HOURS)
public SortedMap<Date, Long> history() throws IOException {
return this.origin.history();
}
}
6 changes: 6 additions & 0 deletions src/main/java/io/jare/dynamo/DyDomain.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.jcabi.dynamo.Attributes;
import com.jcabi.dynamo.Item;
import io.jare.model.Domain;
import io.jare.model.Usage;
import java.io.IOException;

/**
Expand Down Expand Up @@ -67,4 +68,9 @@ public void delete() throws IOException {
);
}

@Override
public Usage usage() throws IOException {
return new DyUsage(this.item);
}

}
172 changes: 172 additions & 0 deletions src/main/java/io/jare/dynamo/DyUsage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 jare.io
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions: the above copyright notice and this
* permission notice shall be included in all copies or substantial
* portions of the Software. The software is provided "as is", without
* warranty of any kind, express or implied, including but not limited to
* the warranties of merchantability, fitness for a particular purpose
* and non-infringement. In no event shall the authors or copyright
* holders be liable for any claim, damages or other liability, whether
* in an action of contract, tort or otherwise, arising from, out of or
* in connection with the software or the use or other dealings in the
* software.
*/
package io.jare.dynamo;

import com.amazonaws.services.dynamodbv2.model.AttributeAction;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.AttributeValueUpdate;
import com.jcabi.aspects.Tv;
import com.jcabi.dynamo.Item;
import com.jcabi.xml.XML;
import com.jcabi.xml.XMLDocument;
import io.jare.model.Usage;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.SortedMap;
import java.util.TimeZone;
import java.util.TreeMap;
import org.apache.commons.lang3.time.DateUtils;
import org.w3c.dom.Node;
import org.xembly.Directives;
import org.xembly.Xembler;

/**
* Dynamo usage.
*
* @author Yegor Bugayenko (yegor@teamed.io)
* @version $Id$
* @since 0.7
* @checkstyle MultipleStringLiteralsCheck (500 lines)
*/
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
public final class DyUsage implements Usage {

/**
* The item.
*/
private final transient Item item;

/**
* Ctor.
* @param itm Item
*/
public DyUsage(final Item itm) {
this.item = itm;
}

@Override
public void add(final Date date, final long bytes) throws IOException {
if (!this.item.has("usage")) {
this.save("<usage/>");
}
final int day = DyUsage.asNumber(date);
final XML xml = new XMLDocument(this.item.get("usage").getS());
final String xpath = String.format("/usage/day[@id='%d']/text()", day);
final List<String> items = xml.xpath(xpath);
final long before;
if (items.isEmpty()) {
before = 0L;
} else {
before = Long.parseLong(items.get(0));
}
final Node node = xml.node();
new Xembler(
new Directives()
.xpath(xpath).up().remove()
.xpath("/usage").add("day").attr("id", day).set(before + bytes)
).applyQuietly(node);
new Xembler(
new Directives().xpath(
String.format(
"/usage/day[number(@id) < %d]",
DyUsage.asNumber(DateUtils.addDays(new Date(), -Tv.TEN))
)
).remove()
).applyQuietly(node);
this.save(new XMLDocument(node).toString());
this.item.put(
"total",
new AttributeValueUpdate().withValue(
new AttributeValue().withN(
new XMLDocument(node).xpath("sum(/usage/day)").get(0)
)
).withAction(AttributeAction.PUT)
);
}

@Override
public long total() throws IOException {
return Long.parseLong(this.item.get("total").getN());
}

@Override
public SortedMap<Date, Long> history() throws IOException {
final XML xml = new XMLDocument(this.item.get("usage").getS());
final SortedMap<Date, Long> map = new TreeMap<>();
for (final XML day : xml.nodes("/usage/day")) {
map.put(
DyUsage.asDate(Integer.parseInt(day.xpath("@id").get(0))),
Long.parseLong(day.xpath("text()").get(0))
);
}
return map;
}

/**
* Save XML.
* @param xml The XML to save
* @throws IOException If fails
*/
private void save(final String xml) throws IOException {
this.item.put(
"usage",
new AttributeValueUpdate()
.withValue(new AttributeValue().withS(xml))
.withAction(AttributeAction.PUT)
);
}

/**
* Convert date to number.
* @param date The date
* @return A number
*/
private static int asNumber(final Date date) {
final TimeZone zone = TimeZone.getTimeZone("UTC");
final DateFormat fmt = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
fmt.setTimeZone(zone);
return Integer.parseInt(fmt.format(date));
}

/**
* Convert number to date.
* @param num The number
* @return A date
*/
private static Date asDate(final int num) {
final TimeZone zone = TimeZone.getTimeZone("UTC");
final DateFormat fmt = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
fmt.setTimeZone(zone);
try {
return fmt.parse(Integer.toString(num));
} catch (final ParseException ex) {
throw new IllegalStateException(ex);
}
}

}
Loading

0 comments on commit 8f14bf0

Please sign in to comment.