Skip to content
This repository has been archived by the owner on Jun 25, 2024. It is now read-only.

Commit

Permalink
Merge pull request #41 from patientsknowbest/feature/PHR-7233_move_hi…
Browse files Browse the repository at this point in the history
…bernate_resources_to_pkb_common

PHR-7233 - Move commons-hibernate optimizer to pkb-common
  • Loading branch information
DMWhiteley committed Oct 20, 2020
2 parents c4b461b + acde60b commit 8f371aa
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 35 deletions.
34 changes: 0 additions & 34 deletions error/src/main/java/com/pkb/common/error/ValidationException.java

This file was deleted.

4 changes: 4 additions & 0 deletions infrastructure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@
<groupId>com.github.karsaig</groupId>
<artifactId>approvalcrest-junit-jupiter</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.pkb.infrastructure.hibernate.id.enhanced;

import java.io.Serializable;

import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.id.enhanced.AccessCallback;
import org.hibernate.id.enhanced.Optimizer;
import org.hibernate.id.enhanced.PooledLoOptimizer;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import com.pkb.common.ClearableInternalState;

/**
* Extend PooledLoOptimizer to track instances and reset internal state (for running tests)
*/
public class ResettablePooledLoOptimizer implements ClearableInternalState, Optimizer {

public static final String OPTIMIZER_CANONICAL_NAME ="com.pkb.infrastructure.hibernate.id.enhanced.ResettablePooledLoOptimizer";

private PooledLoOptimizer optimizer;

// only used for resetting state (in e2e tests)
private static final Cache<ClearableInternalState, Boolean> clearableInstances = CacheBuilder.newBuilder()
.weakKeys()
.build();
private boolean lazyAddedToCache = false;

/**
* Constructs a ResettablePooledLoOptimizer.
*
* @param returnClass The Java type of the values to be generated
* @param incrementSize The increment size.
*/
@SuppressWarnings("rawtypes")
public ResettablePooledLoOptimizer(Class returnClass, int incrementSize) {
this.optimizer = newOptimizer(returnClass, incrementSize);
}

@SuppressWarnings("rawtypes")
private PooledLoOptimizer newOptimizer(Class returnClass, int incrementSize) {
return new PooledLoOptimizer(returnClass, incrementSize);
}

@Override
public void clearState() {
this.optimizer = newOptimizer(optimizer.getReturnClass(), optimizer.getIncrementSize());
}

public static void clearStateGlobal() {
for (ClearableInternalState instance : clearableInstances.asMap().keySet()) {
instance.clearState();
}
}

@Override
public synchronized Serializable generate(AccessCallback callback) {
if (!lazyAddedToCache) {
//noinspection AccessToStaticFieldLockedOnInstance
clearableInstances.put(this, Boolean.TRUE);
lazyAddedToCache = true;
}
return optimizer.generate(callback);
}

@Override
public boolean applyIncrementSizeToSourceValues() {
return optimizer.applyIncrementSizeToSourceValues();
}

@Override
public final int getIncrementSize() {
return optimizer.getIncrementSize();
}

@Override
public IntegralDataTypeHolder getLastSourceValue() {
return optimizer.getLastSourceValue();
}

/**
* Getter for property 'returnClass'. This is the Java
* class which is used to represent the id (e.g. {@link Long}).
*
* @return Value for property 'returnClass'.
*/
@SuppressWarnings({"UnusedDeclaration", "rawtypes"})
public final Class getReturnClass() {
return optimizer.getReturnClass();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package com.pkb.infrastructure.hibernate.id.enhanced;

import static com.github.karsaig.approvalcrest.MatcherAssert.assertThat;
import static com.pkb.infrastructure.hibernate.id.enhanced.ResettablePooledLoOptimizer.OPTIMIZER_CANONICAL_NAME;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.junit.Assert.assertEquals;

import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.id.enhanced.AccessCallback;
import org.hibernate.id.enhanced.Optimizer;
import org.hibernate.id.enhanced.OptimizerFactory;
import org.junit.Test;

public class ResettablePooledLoOptimizerTest {

@Test
public void optimizerFoundByHibernate() {
Optimizer optimizer = OptimizerFactory.buildOptimizer(OPTIMIZER_CANONICAL_NAME, Long.class, 50, -1);

assertThat(optimizer, instanceOf(ResettablePooledLoOptimizer.class));
}

@Test
public void optimizerBasicUsage() {
SourceMock sequence = new SourceMock(1, 3);
Optimizer optimizer = OptimizerFactory.buildOptimizer(ResettablePooledLoOptimizer.class.getCanonicalName(), Long.class, 3, 1);

assertEquals(0, sequence.getTimesCalled());
assertEquals(-1, sequence.getCurrentValue());

Long next = (Long)optimizer.generate(sequence);
assertEquals(1, next.intValue());
assertEquals(1, sequence.getTimesCalled());
assertEquals(1, sequence.getCurrentValue());

next = (Long)optimizer.generate(sequence);
assertEquals(2, next.intValue());
assertEquals(1, sequence.getTimesCalled());
assertEquals(1, sequence.getCurrentValue());

next = (Long)optimizer.generate(sequence);
assertEquals(3, next.intValue());
assertEquals(1, sequence.getTimesCalled());
assertEquals(1, sequence.getCurrentValue());

next = (Long)optimizer.generate(sequence);
assertEquals(4, next.intValue());
assertEquals(2, sequence.getTimesCalled());
assertEquals(4, sequence.getCurrentValue());
}

@Test
public void optimizerResetCausesIncrementEarlier() {
SourceMock sequence = new SourceMock(1, 3);
ResettablePooledLoOptimizer optimizer = (ResettablePooledLoOptimizer)OptimizerFactory.buildOptimizer(
ResettablePooledLoOptimizer.class.getCanonicalName(),
Long.class,
3,
1);

assertEquals(0, sequence.getTimesCalled());
assertEquals(-1, sequence.getCurrentValue());

Long next = (Long)optimizer.generate(sequence);
assertEquals(1, next.intValue());
assertEquals(1, sequence.getTimesCalled());
assertEquals(1, sequence.getCurrentValue());

ResettablePooledLoOptimizer.clearStateGlobal();

next = (Long)optimizer.generate(sequence);
assertEquals(4, next.intValue());
assertEquals(2, sequence.getTimesCalled());
assertEquals(4, sequence.getCurrentValue());

next = (Long)optimizer.generate(sequence);
assertEquals(5, next.intValue());
assertEquals(2, sequence.getTimesCalled());
assertEquals(4, sequence.getCurrentValue());
}

/**
* Largely pulled from hibernate-core's org.hibernate.id.enhanced.OptimizerUnitTest.SourceMock
*/
private static class SourceMock implements AccessCallback {
private IdentifierGeneratorHelper.BasicHolder value = new IdentifierGeneratorHelper.BasicHolder(Long.class);
private long initialValue;
private int increment;
private int timesCalled ;

private SourceMock(long initialValue, int increment) {
this(initialValue, increment, 0 );
}

private SourceMock(long initialValue, int increment, int timesCalled) {
this.increment = increment;
this.timesCalled = timesCalled;

if (timesCalled == 0) {
this.value.initialize( -1 );
this.initialValue = initialValue;
}
else {
this.value.initialize( initialValue );
this.initialValue = 1;
}
}

@Override
public IntegralDataTypeHolder getNextValue() {
try {
if (timesCalled == 0) {
initValue();
return value.copy();
}
else {
return value.add(increment).copy();
}
}
finally {
timesCalled++;
}
}

@Override
public String getTenantIdentifier() {
return "test";
}

private void initValue() {
this.value.initialize(initialValue);
}

private int getTimesCalled() {
return timesCalled;
}

private long getCurrentValue() {
return value == null ? -1 : value.getActualLongValue();
}
}

}
18 changes: 18 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
<javax.inject.version>1</javax.inject.version>
<phr-pulsar.version>12-a115018-86851</phr-pulsar.version>
<restassured.version>3.0.7-PKB</restassured.version>

<hibernate-core.version>5.3.15.Final</hibernate-core.version>
</properties>

<modules>
Expand Down Expand Up @@ -208,6 +210,22 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate-core.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.fasterxml</groupId>
<artifactId>classmate</artifactId>
</exclusion>
<exclusion>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down
6 changes: 5 additions & 1 deletion spring-infrastructure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
<groupId>com.pkb</groupId>
<artifactId>rest-assured</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
</dependencies>


Expand All @@ -76,4 +80,4 @@
</plugin>
</plugins>
</build>
</project>
</project>
7 changes: 7 additions & 0 deletions suppression.xml
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,11 @@
<packageUrl regex="true">^pkg:maven/org\.yaml/snakeyaml@.*$</packageUrl>
<cve>CVE-2017-18640</cve>
</suppress>
<!-- This is a wildfly provided dependency, so cannot be changed unless we upgrade our wf version-->
<suppress until="2021-10-07">
<notes><![CDATA[
file name: hibernate-core-5.3.15.Final.jar
]]></notes>
<cve>CVE-2019-14900</cve>
</suppress>
</suppressions>

0 comments on commit 8f371aa

Please sign in to comment.