diff --git a/BaseIntegrationTest.java b/BaseIntegrationTest.java new file mode 100644 index 0000000..aa7dc53 --- /dev/null +++ b/BaseIntegrationTest.java @@ -0,0 +1,26 @@ +package com.example.crud; + +import example.domain.Event; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cassandra.core.cql.CqlIdentifier; +import org.springframework.data.cassandra.core.CassandraAdminOperations; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.HashMap; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = CassandraConfiguration.class) +public abstract class BaseIntegrationTest { + + @Autowired + private CassandraAdminOperations adminTemplate; + + @Before + public void resetKeySpace() { + adminTemplate.dropTable(CqlIdentifier.cqlId("event")); + adminTemplate.createTable(true, CqlIdentifier.cqlId("event"), Event.class, new HashMap()); + } +} diff --git a/CRUDTest.java b/CRUDTest.java new file mode 100644 index 0000000..4c1b29c --- /dev/null +++ b/CRUDTest.java @@ -0,0 +1,219 @@ +package com.example.crud.entities; + +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; +import lombok.extern.java.Log; +import org.junit.*; + +import javax.persistence.*; +import java.util.HashMap; +import java.util.Map; + +/** + * The Class CRUDTest. + */ +public class CRUDTest +{ + private Log log = LogFactory.getLog(getClass().getName()); + + /** The Constant PU. */ + private static final String PU = "cassandra_pu"; + + /** The emf. */ + private static EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + /** + * Sets the up before class. + * + * @throws Exception + * the exception + */ + @BeforeClass + public static void SetUpBeforeClass() throws Exception + { + Map propertyMap = new HashMap(); + //propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + propertyMap.put("kundera.batch.size", "5"); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + emf = Persistence.createEntityManagerFactory(PU, propertyMap); + } + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + em = emf.createEntityManager(); + } + + /** + * Test crud operations. + * + * @throws Exception + * the exception + */ + @Test + public void testCRUDOperations() throws Exception + { + testInsert(); + testMerge(); + testUpdate(); + testCache(); + testTransaction(); + testBatch(); + testQueryBuilder(); + testRemove(); + } + + /** + * Test insert. + * + * @throws Exception + * the exception + */ + private void testInsert() throws Exception + { + Person p = new Person(); + p.setPersonId("101"); + p.setPersonFirstName("James"); + p.setPersonLastName("Bond"); + p.setAge(24); + //p.addEmail("007@mi6.gov"); + em.persist(p); + em.flush(); + + Person person = em.find(Person.class, "101"); + Assert.assertNotNull(person); + Assert.assertEquals("101", person.getPersonId()); + Assert.assertEquals("James Bond", person.getPersonName()); + } + + /** + * Test merge. + */ + private void testMerge() + { + Person person = em.find(Person.class, "101"); + person.setPersonLastName("Blond"); + //person.addEmail("jamesbond@gmail.com"); + person = em.merge(person); + em.flush(); + + Person p2 = em.find(Person.class, "101"); + Assert.assertEquals("Blond", p2.getPersonLastName()); + } + + private void testCache() { + Cache cache = emf.getCache(); + cache.evictAll(); + log.info("Person in Cache: " + cache.contains(Person.class, "101")); + Person person = em.find(Person.class, "101"); + log.info("Person in Cache: " + cache.contains(Person.class, person.getPersonId())); + cache.evictAll(); + log.info("Person in Cache: " + cache.contains(Person.class, person.getPersonId())); + } + + private void testUpdate() + { + Person person = em.find(Person.class, "101"); + /* + // In Query set Paramater. + queryString = "Update PersonCassandra p SET p.personName = 'Kuldeep' WHERE p.personId IN :idList"; + + List id = new ArrayList(); + id.add("1"); + id.add("2"); + id.add("3"); + + cqlQuery = parseAndCreateUpdateQuery(kunderaQuery, emf, em, pu, PersonCassandra.class, Integer.MAX_VALUE); + KunderaQuery kunderaQuery = getQueryObject(queryString, emf); + kunderaQuery.setParameter("idList", id); + + PersistenceDelegator pd = getPersistenceDelegator(em, getpd); + EntityManagerFactoryImpl.KunderaMetadata kunderaMetadata = ((EntityManagerFactoryImpl) emf).getKunderaMetadataInstance(); + + CassQuery query = new CassQuery(kunderaQuery, pd, kunderaMetadata); + query.setMaxResults(maxResult); + if(ttl != null) + { + query.applyTTL(ttl); + } + + String cqlQuery = query.createUpdateQuery(kunderaQuery); + return cqlQuery; + */ + person.setPersonFirstName("Jim"); + em.flush(); + } + + private void testTransaction() + { + EntityTransaction txn = em.getTransaction(); + txn.begin(); + Person person = new Person(); + person.setPersonFirstName("Fred"); + person.setPersonLastName("Johnson"); + person.setAge(22); + em.persist(person); + txn.commit(); + } + + private void testBatch() + { + } + + private void testQueryBuilder() + { + String table = em.getMetamodel().entity(Person.class).getName(); + Select q = QueryBuilder.select().all().from(table); + Query query = em.createQuery(q.getQueryString()); + query.getResultList(); + } + + /** + * Test remove. + */ + private void testRemove() + { + Person p = em.find(Person.class, "101"); + em.remove(p); + + Person p1 = em.find(Person.class, "101"); + Assert.assertNull(p1); + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + em.close(); + } + + /** + * Tear down after class. + * + * @throws Exception + * the exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception + { + if (emf != null) + { + emf.close(); + emf = null; + } + } +} diff --git a/CacheProperties.java b/CacheProperties.java new file mode 100644 index 0000000..fd00ca3 --- /dev/null +++ b/CacheProperties.java @@ -0,0 +1,39 @@ +package com.example.crud; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +@Component +@PropertySource("application.properties") +public class CacheProperties { + @Value("${cache.enabled}") + private boolean enabled; + + @Value("${cache.names}") + private String[] cacheNames; + + public List getCacheNameList() { + return Collections.unmodifiableList(Arrays.asList(cacheNames)); + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String[] getCacheNames() { + return cacheNames; + } + + public void setCacheNames(String[] cacheNames) { + this.cacheNames = cacheNames; + } +} diff --git a/CassandraConfiguration.java b/CassandraConfiguration.java new file mode 100644 index 0000000..2302c0b --- /dev/null +++ b/CassandraConfiguration.java @@ -0,0 +1,43 @@ +package com.example.crud; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.data.cassandra.config.CassandraClusterFactoryBean; +import org.springframework.data.cassandra.config.java.AbstractCassandraConfiguration; +import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext; +import org.springframework.data.cassandra.mapping.CassandraMappingContext; +import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories; + +@Configuration +@PropertySource(value = {"classpath:cassandra.properties"}) +@EnableCassandraRepositories(basePackages = {"example"}) +public class CassandraConfiguration extends AbstractCassandraConfiguration { + + private static final Logger LOG = LoggerFactory.getLogger(CassandraConfiguration.class); + + @Autowired + private Environment environment; + + @Bean + public CassandraClusterFactoryBean cluster() { + CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean(); + cluster.setContactPoints(environment.getProperty("cassandra.contactpoints")); + cluster.setPort(Integer.parseInt(environment.getProperty("cassandra.port"))); + return cluster; + } + + @Override + protected String getKeyspaceName() { + return environment.getProperty("cassandra.keyspace"); + } + + @Bean + public CassandraMappingContext cassandraMapping() throws ClassNotFoundException { + return new BasicCassandraMappingContext(); + } +} \ No newline at end of file diff --git a/CassandraTemplateIntegrationTest.java b/CassandraTemplateIntegrationTest.java new file mode 100644 index 0000000..2ee717d --- /dev/null +++ b/CassandraTemplateIntegrationTest.java @@ -0,0 +1,42 @@ +pacakage com.example.crud; + +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; +import com.datastax.driver.core.utils.UUIDs; +import com.google.common.collect.ImmutableSet; +import example.domain.Event; +import org.hamcrest.core.IsEqual; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.cassandra.core.CassandraOperations; + +import java.util.List; + +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class CassandraTemplateIntegrationTest extends BaseIntegrationTest { + + public static final String TIME_BUCKET = "2014-01-01"; + + @Autowired + private CassandraOperations cassandraTemplate; + + @Test + public void supportsPojoToCqlMappings() { + Event event = new Event(UUIDs.timeBased(), "type1", TIME_BUCKET, ImmutableSet.of("tag1", "tag3")); + cassandraTemplate.insert(event); + + Select select = QueryBuilder.select().from("event").where(QueryBuilder.eq("type", "type1")).and(QueryBuilder.eq("bucket", TIME_BUCKET)).limit(10); + + Event retrievedEvent = cassandraTemplate.selectOne(select, Event.class); + + assertThat(retrievedEvent, IsEqual.equalTo(event)); + + List retrievedEvents = cassandraTemplate.select(select, Event.class); + + assertThat(retrievedEvents.size(), is(1)); + assertThat(retrievedEvents, hasItem(event)); + } +} diff --git a/CqlTemplateIntegrationTest.java b/CqlTemplateIntegrationTest.java new file mode 100644 index 0000000..e8cd3cf --- /dev/null +++ b/CqlTemplateIntegrationTest.java @@ -0,0 +1,56 @@ +package com.example.crud; + +import com.datastax.driver.core.PreparedStatement; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Statement; +import com.datastax.driver.core.querybuilder.Insert; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; +import com.datastax.driver.core.utils.UUIDs; +import com.google.common.collect.ImmutableSet; +import org.hamcrest.core.Is; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cassandra.core.CqlOperations; + +import static org.junit.Assert.assertThat; + +public class CqlTemplateIntegrationTest extends BaseIntegrationTest { + + public static final String TIME_BUCKET = "2014-01-01"; + + @Autowired + private CqlOperations cqlTemplate; + + @Test + public void allowsExecutingCqlStatements() { + insertEventUsingCqlString(); + insertEventUsingStatementBuildWithQueryBuilder(); + insertEventUsingPreparedStatement(); + + ResultSet resultSet1 = cqlTemplate.query("select * from event where type='type2' and bucket='" + TIME_BUCKET + "'"); + + assertThat(resultSet1.all().size(), Is.is(2)); + + Select select = QueryBuilder.select().from("event").where(QueryBuilder.eq("type", "type1")).and(QueryBuilder.eq("bucket", TIME_BUCKET)).limit(10); + ResultSet resultSet2 = cqlTemplate.query(select); + + assertThat(resultSet2.all().size(), Is.is(1)); + } + + private void insertEventUsingCqlString() { + cqlTemplate.execute("insert into event (id, type, bucket, tags) values (" + UUIDs.timeBased() + ", 'type1', '" + TIME_BUCKET + "', {'tag2', 'tag3'})"); + } + + private void insertEventUsingStatementBuildWithQueryBuilder() { + Insert insertStatement = QueryBuilder.insertInto("event").value("id", UUIDs.timeBased()).value("type", "type2") + .value("bucket", TIME_BUCKET).value("tags", ImmutableSet.of("tag1")); + cqlTemplate.execute(insertStatement); + } + + private void insertEventUsingPreparedStatement() { + PreparedStatement preparedStatement = cqlTemplate.getSession().prepare("insert into event (id, type, bucket, tags) values (?, ?, ?, ?)"); + Statement insertStatement = preparedStatement.bind(UUIDs.timeBased(), "type2", TIME_BUCKET, ImmutableSet.of("tag1", "tag2")); + cqlTemplate.execute(insertStatement); + } +} diff --git a/README b/README index 2330129..bab46a6 100644 --- a/README +++ b/README @@ -17,3 +17,6 @@ netstat -nr | grep 239.9.9.9 ping -t 1 -c 2 239.9.9.9 sudo tcpdump -vvv -ni en0 host 239.9.9.9 sudo route -v delete -inet 239.9.9.9 + +mvn clean versions:use-latest-versions scm:checkin deploy -Dmessage="update versions" -DperformRelease=true +http://www.mojohaus.org/versions-maven-plugin/index.html diff --git a/RedisCacheConfiguration.java b/RedisCacheConfiguration.java new file mode 100644 index 0000000..0491d0f --- /dev/null +++ b/RedisCacheConfiguration.java @@ -0,0 +1,37 @@ +@Configuration +@EnableCaching +public class CacheConfig { + + @Bean + public JedisConnectionFactory redisConnectionFactory() { + return new JedisConnectionFactory(); + } + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory cf) { + RedisTemplate redisTemplate = new RedisTemplate(); + redisTemplate.setConnectionFactory(cf); + return redisTemplate; + } + + @Bean + public CacheManager cacheManager(RedisTemplate redisTemplate) { + return new RedisCacheManager(redisTemplate); + } + + @Bean + public KeyGenerator keyGenerator() { + return new KeyGenerator() { + @Override + public Object generate(Object o, Method method, Object... params) { + StringBuilder sb = new StringBuilder(); + sb.append(o.getClass().getName()); + sb.append(method.getName()); + for (Object param : params) { + sb.append(param.toString()); + } + return sb.toString(); + } + }; + } +} diff --git a/TESTS b/TESTS new file mode 100644 index 0000000..e69de29 diff --git a/application.properties b/application.properties new file mode 100644 index 0000000..c2988cd --- /dev/null +++ b/application.properties @@ -0,0 +1,5 @@ +################ +# Caching +################ +cache.enabled = true +cache.names = crudCache diff --git a/applicationContext.xml b/applicationContext.xml new file mode 100644 index 0000000..1c57c06 --- /dev/null +++ b/applicationContext.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crud.iml b/crud.iml index add7feb..109baf3 100644 --- a/crud.iml +++ b/crud.iml @@ -15,13 +15,22 @@ - file://$MODULE_DIR$/src/main/java/com/example/crud/ApplicationConfig.java file://$MODULE_DIR$/src/main/java/com/example/crud/CacheConfiguration.java file://$MODULE_DIR$/src/main/java/com/example/crud/EhCacheConfiguration.java file://$MODULE_DIR$/src/main/java/com/example/crud/metrics/MetricsConfiguration.java file://$MODULE_DIR$/src/main/java/com/example/crud/metrics/SpringConfiguringClass.java file://$MODULE_DIR$/applicationContext.xml + + file://$MODULE_DIR$/src/main/java/com/example/crud/ApplicationConfiguration.java + + + file://$MODULE_DIR$/src/main/java/com/example/crud/ApplicationConfiguration.java + file://$MODULE_DIR$/src/main/java/com/example/crud/CacheConfiguration.java + file://$MODULE_DIR$/src/main/java/com/example/crud/EhCacheConfiguration.java + file://$MODULE_DIR$/src/main/java/com/example/crud/metrics/MetricsConfiguration.java + file://$MODULE_DIR$/src/main/java/com/example/crud/metrics/SpringConfiguringClass.java + @@ -41,16 +50,24 @@ - - - - + + + + - - + + - + + + + + + + + + @@ -69,44 +86,45 @@ + + - - - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + - + + diff --git a/pom.xml b/pom.xml index 7bf786f..9832529 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ [5.1.0-m3, 5.9) 1.8.10 3.2.2 - 5.0.0.M5 + 5.0.0.RC2 Kay-M4 @@ -46,7 +46,7 @@ org.springframework spring-framework-bom - ${spring.version} + 5.0.0.RC2 import pom @@ -54,7 +54,7 @@ org.springframework.data spring-data-releasetrain - ${spring-data.version} + 1.4.6.RELEASE import pom @@ -77,13 +77,13 @@ org.datanucleus javax.persistence - 2.1.0 + 2.2.0-m3 ch.qos.logback logback-classic - 1.0.13 + 1.2.3 ch.qos.logback @@ -93,12 +93,12 @@ org.slf4j jcl-over-slf4j - 1.7.25 + 1.8.0-alpha2 org.slf4j log4j-over-slf4j - 1.7.7 + 1.8.0-alpha2 @@ -117,24 +117,41 @@ org.datanucleus datanucleus-cassandra - ${org.datanucleus.version} + + jar + system + 5.1.0-m4-SNAPSHOT + ${project.basedir}/lib/datanucleus-cassandra-5.1.0-m4-SNAPSHOT.jar + com.datastax.cassandra cassandra-driver-core 3.2.0 + + com.datastax.cassandra + cassandra-driver-extras + 3.2.0 + + + + com.datastax.cassandra + cassandra-driver-mapping + 3.2.0 + + org.hdrhistogram HdrHistogram - [2.1.8,) + 2.1.9 org.datanucleus datanucleus-cache - 5.0.0-release + 5.1.0-m1 + org.datanucleus datanucleus-maven-plugin @@ -451,7 +473,7 @@ - --> + org.codehaus.mojo diff --git a/src/main/java/com/example/crud/CacheConfiguration.java b/src/main/java/com/example/crud/CacheConfiguration.java index 66489ba..8b8985e 100644 --- a/src/main/java/com/example/crud/CacheConfiguration.java +++ b/src/main/java/com/example/crud/CacheConfiguration.java @@ -1,5 +1,6 @@ package com.example.crud; +import com.codahale.metrics.ehcache.InstrumentedEhcache; import com.google.common.collect.Lists; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; diff --git a/src/main/java/com/example/crud/Main.java b/src/main/java/com/example/crud/Main.java index 272e9a4..2c106cb 100644 --- a/src/main/java/com/example/crud/Main.java +++ b/src/main/java/com/example/crud/Main.java @@ -1,5 +1,9 @@ package com.example.crud; +import com.codahale.metrics.ehcache.InstrumentedEhcache; +import com.datastax.driver.core.*; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; import com.example.crud.entities.*; import com.example.crud.repositories.InventoryRepository; import com.example.crud.repositories.PersonRepository; @@ -16,67 +20,113 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +// TODO: +// * LOCAL_QUORUM +// * compound primary keys +// * pillar for DDL +// * metrics +// * com.datastax.driver.core.Cluster.builder().withQueryOptions(‌​new QueryOptions().setConsistencyLevel(ConsistencyLevel.QUORUM)) +// * https://github.com/brndnmtthws/metrics-cassandra (c* as a sink for metrics) +// * https://github.com/addthis/metrics-reporter-config + + /** * Controlling application for the DataNucleus Tutorial using JPA. * Uses the "persistence-unit" called "Tutorial". */ public class Main { + Logger log = LoggerFactory.getLogger(getClass().getName()); + EntityManagerFactory cassandraEntityManagerFactory; + EntityManagerFactory mongoEntityManagerFactory; + Cluster cluster; + + String personId; public static void main(String args[]) { - Logger log = LoggerFactory.getLogger(Main.class);//getClass().getName()); + Main main = new Main(); + } + + public Main() { + System.setProperty("DEBUG.MONGO", "true"); // Enable MongoDB logging in general + System.setProperty("DB.TRACE", "true"); // Enable DB operation tracing AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.scan("com.example"); ctx.register(ApplicationConfiguration.class); ctx.refresh(); - // Enable MongoDB logging in general - System.setProperty("DEBUG.MONGO", "true"); - - // Enable DB operation tracing - System.setProperty("DB.TRACE", "true"); - // Create an EntityManagerFactory for this "persistence-unit" // See the file "META-INF/persistence.xml" - EntityManagerFactory cassandraEntityManagerFactory = Persistence.createEntityManagerFactory("crud"); - EntityManagerFactory mongoEntityManagerFactory = Persistence.createEntityManagerFactory("mongo"); + cassandraEntityManagerFactory = Persistence.createEntityManagerFactory("crud"); + mongoEntityManagerFactory = Persistence.createEntityManagerFactory("mongo"); - // TODO: - // * LOCAL_QUORUM - // * compound primary keys - // * pillar for DDL - // * metrics - // * com.datastax.driver.core.Cluster.builder().withQueryOptions(‌​new QueryOptions().setConsistencyLevel(ConsistencyLevel.QUORUM)) - // * https://github.com/brndnmtthws/metrics-cassandra (c* as a sink for metrics) - // * https://github.com/addthis/metrics-reporter-config + cluster = ctx.getBean(Cluster.class); + /* + Configuration configuration = cluster.getConfiguration(); + Metadata metadata = cluster.getMetadata(); + log.debug(configuration); + log.debug(metadata); */ + /* + Session session = ctx.getBean(Session.class); + Select s = QueryBuilder.select().all().from("kc", "inventory"); + s.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM); + ResultSet rs = session.execute(s); + log.debug(rs.toString()); + */ + /* + //org.datanucleus.api.jpa.JPAEntityTransaction tx = (org.datanucleus.api.jpa.JPAEntityTransaction)pm.currentTransaction(); + //tx.setOption("transaction.isolation", 2); + */ + this.a().b().c().e().f().g().z(); + cassandraEntityManagerFactory.close(); + } + + public Main a() { EntityManager em; EntityTransaction tx; - JpaRepositoryFactory factory; - //org.datanucleus.api.jpa.JPAEntityTransaction tx = (org.datanucleus.api.jpa.JPAEntityTransaction)pm.currentTransaction(); - //tx.setOption("transaction.isolation", 2); - - // Add a person to MongoDB - em = mongoEntityManagerFactory.createEntityManager(); - Person person; - /* - factory = new JpaRepositoryFactory(em); - PersonRepository repository = factory.getRepository(PersonRepository.class); - person = new Person(); - person.setPersonFirstName("James"); - person.setPersonLastName("Bond"); - person.setAge(42); - repository.save(person); - */ + em = cassandraEntityManagerFactory.createEntityManager(); + JpaRepositoryFactory factory = new JpaRepositoryFactory(em); tx = em.getTransaction(); try { tx.begin(); - person = new Person(); + InventoryRepository repository = factory.getRepository(InventoryRepository.class); + Inventory inventory = repository.findByName("My Inventory"); + if (inventory == null) { + inventory = new Inventory("My Inventory"); + } + log.debug("SpringData/JPA: " + inventory.toString()); + inventory.setDescription("This is my updated description."); + tx.rollback(); + } + catch (Exception e) { + log.error(">> Exception in bulk delete of data", e); + System.err.println("Error in bulk delete of data : " + e.getMessage()); + } finally { + if (tx.isActive()) { + tx.rollback(); + } + em.close(); + } + return this; + } + + public Main b() { + EntityManager em; + EntityTransaction tx; + + // Add a person to MongoDB + em = mongoEntityManagerFactory.createEntityManager(); + tx = em.getTransaction(); + try { + tx.begin(); + Person person = new Person(); person.setPersonFirstName("James"); person.setPersonLastName("Bond"); person.setAge(42); + personId = person.getPersonId(); em.merge(person); List objs = ((JPAEntityManager) em).getExecutionContext().getObjectsToBeFlushed(); @@ -90,6 +140,12 @@ public class Main { } em.close(); // This will detach all current managed objects } + return this; + } + + public Main c() { + EntityManager em; + EntityTransaction tx; // Persistence of a Product and a Book. em = cassandraEntityManagerFactory.createEntityManager(); @@ -118,7 +174,6 @@ public class Main { catch (Exception e) { log.error(">> Exception persisting data", e); System.err.println("Error persisting data : " + e.getMessage()); - return; } finally { if (tx.isActive()) { tx.rollback(); @@ -126,7 +181,13 @@ public class Main { em.close(); } cassandraEntityManagerFactory.getCache().evictAll(); - System.out.println(""); + log.debug(""); + return this; + } + + public Main d() { + EntityManager em; + EntityTransaction tx; // Perform a retrieve of the Inventory and detach it (by closing the EM) em = cassandraEntityManagerFactory.createEntityManager(); @@ -140,19 +201,18 @@ public class Main { // Note : you could achieve the same by either // 1). access the Inventory.products field before commit // 2). set fetch=EAGER for the Inventory.products field - System.out.println("Executing find() on Inventory"); + log.debug("Executing find() on Inventory"); EntityGraph allGraph = em.getEntityGraph("allProps"); Map hints = new HashMap(); - hints.put("javax.persistence.loadgraph", allGraph); + hints.put("javax.persistence.loadgraph", allGraph); // <- not yet supported, ignore this inv = em.find(Inventory.class, "My Inventory", hints); - System.out.println("Retrieved Inventory as " + inv); + log.debug("Retrieved Inventory as " + inv); tx.commit(); } catch (Exception e) { log.error(">> Exception performing find() on data", e); System.err.println("Error performing find() on data : " + e.getMessage()); - return; } finally { if (tx.isActive()) { tx.rollback(); @@ -160,38 +220,54 @@ public class Main { em.close(); // This will detach all current managed objects } for (Product prod : inv.getProducts()) { - System.out.println(">> After Detach : Inventory has a product=" + prod); + log.debug(">> After Detach : Inventory has a product=" + prod); } - System.out.println(""); + log.debug(""); + return this; + } + + public Main e() { + EntityManager em; + EntityTransaction tx; // Update a person to MongoDB em = mongoEntityManagerFactory.createEntityManager(); tx = em.getTransaction(); try { tx.begin(); - person = em.find(Person.class, person.getPersonId()); - person.setPersonLastName("Blunder"); - person.setAge(43); - tx.commit(); + if (personId == null) { + tx.rollback(); + } else { + Person person = em.find(Person.class, personId); + person.setPersonLastName("Blunder"); + person.setAge(43); + tx.commit(); + } } finally { if (tx.isActive()) { tx.rollback(); } em.close(); // This will detach all current managed objects } + return this; + } + + public Main f() { + EntityManager em; + EntityTransaction tx; // Perform some query operations em = cassandraEntityManagerFactory.createEntityManager(); tx = em.getTransaction(); try { tx.begin(); - System.out.println("Executing Query for Products with price below 150.00"); + log.debug("Executing Query for Products with price below 150.00"); Query q = em.createQuery("SELECT p FROM Product p WHERE p.price < 150.00 ORDER BY p.price"); List results = q.getResultList(); Iterator iter = results.iterator(); while (iter.hasNext()) { Object obj = iter.next(); - System.out.println("> " + obj); + log.debug("> " + obj); // Give an example of an update if (obj instanceof Book) { Book b = (Book) obj; @@ -202,45 +278,27 @@ public class Main { m.setDescription(m.getDescription() + " SPECIAL"); } } - tx.commit(); } catch (Exception e) { log.error(">> Exception querying data", e); System.err.println("Error querying data : " + e.getMessage()); - return; } finally { if (tx.isActive()) { tx.rollback(); } em.close(); } - System.out.println(""); + log.debug(""); + return this; + } + + public Main g() { + EntityManager em; + EntityTransaction tx; em = cassandraEntityManagerFactory.createEntityManager(); - factory = new JpaRepositoryFactory(em); - tx = em.getTransaction(); - try { - tx.begin(); - InventoryRepository repository = factory.getRepository(InventoryRepository.class); - Inventory inventory = repository.findByName("My Inventory"); - System.out.println("SpringData/JPA: " + inventory.toString()); - inventory.setDescription("This is my updated description."); - tx.rollback(); - } - catch (Exception e) { - log.error(">> Exception in bulk delete of data", e); - System.err.println("Error in bulk delete of data : " + e.getMessage()); - return; - } finally { - if (tx.isActive()) { - tx.rollback(); - } - em.close(); - } - - em = cassandraEntityManagerFactory.createEntityManager(); - factory = new JpaRepositoryFactory(em); + JpaRepositoryFactory factory = new JpaRepositoryFactory(em); tx = em.getTransaction(); try { tx.begin(); @@ -253,14 +311,18 @@ public class Main { catch (Exception e) { log.error(">> Exception in bulk delete of data", e); System.err.println("Error in bulk delete of data : " + e.getMessage()); - return; } finally { if (tx.isActive()) { tx.rollback(); } em.close(); } + return this; + } + public Main z() { + EntityManager em; + EntityTransaction tx; // Clean out the database cassandraEntityManagerFactory.getCache().evictAll(); @@ -269,17 +331,17 @@ public class Main { try { tx.begin(); - System.out.println("Deleting all products from persistence"); - inv = (Inventory) em.find(Inventory.class, "My Inventory"); + log.debug("Deleting all products from persistence"); + Inventory inv = (Inventory) em.find(Inventory.class, "My Inventory"); - System.out.println("Clearing out Inventory"); + log.debug("Clearing out Inventory"); inv.clearProducts(); em.flush(); - System.out.println("Deleting Inventory"); + log.debug("Deleting Inventory"); em.remove(inv); - System.out.println("Deleting all products from persistence"); + log.debug("Deleting all products from persistence"); Query q = em.createQuery("SELECT p FROM Product p"); List products = q.getResultList(); int numDeleted = 0; @@ -287,23 +349,19 @@ public class Main { em.remove(prod); numDeleted++; } - System.out.println("Deleted " + numDeleted + " products"); + log.debug("Deleted " + numDeleted + " products"); tx.commit(); } catch (Exception e) { log.error(">> Exception in bulk delete of data", e); System.err.println("Error in bulk delete of data : " + e.getMessage()); - return; } finally { if (tx.isActive()) { tx.rollback(); } em.close(); } - - System.out.println(""); - System.out.println("End of Tutorial"); - cassandraEntityManagerFactory.close(); + return this; } } diff --git a/src/main/java/com/example/crud/entities/Inventory.java b/src/main/java/com/example/crud/entities/Inventory.java index 379b63d..07f04d4 100644 --- a/src/main/java/com/example/crud/entities/Inventory.java +++ b/src/main/java/com/example/crud/entities/Inventory.java @@ -1,34 +1,44 @@ package com.example.crud.entities; import com.google.common.collect.ImmutableSet; -import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; import lombok.ToString; +import org.datanucleus.api.jpa.annotations.DatastoreId; import javax.persistence.*; +import java.io.Serializable; import java.util.HashSet; import java.util.Set; /** * Definition of an Inventory of products. */ -@Data @Entity -@ToString +@DatastoreId @NamedEntityGraph(name = "allProps", attributeNodes = { @NamedAttributeNode("name"), @NamedAttributeNode("products") }) +@ToString +@EqualsAndHashCode +@Getter @Setter +@IdClass(Inventory.ID.class) public class Inventory extends AbstractAuditableEntity { @Id private String name=null; + @Id + private String region=null; + @Basic private String description; - @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH }, fetch = FetchType.EAGER) - private Set products = new HashSet(); - public Inventory() { } + @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH }, fetch = FetchType.EAGER) + private Set products = new HashSet(); + public Inventory(String name) { this.name = name; } @@ -37,7 +47,7 @@ public class Inventory extends AbstractAuditableEntity { products.add(product); } - public Iterable getProducts() { + public ImmutableSet getProducts() { return ImmutableSet.copyOf(products); } @@ -48,4 +58,9 @@ public class Inventory extends AbstractAuditableEntity { public void setDescription(String description) { this.description = description; } + + class ID implements Serializable { + String name; + String region; + } } diff --git a/src/main/java/com/example/crud/entities/Person.java b/src/main/java/com/example/crud/entities/Person.java index 8655989..9836c1c 100644 --- a/src/main/java/com/example/crud/entities/Person.java +++ b/src/main/java/com/example/crud/entities/Person.java @@ -48,8 +48,10 @@ public class Person extends AbstractAuditableEntity { * @Temporal(TemporalType.DATE) private Date updated; */ + /* @OneToMany(mappedBy = "seller") private List products; + */ public Person() { } diff --git a/src/main/java/com/example/crud/entities/Product.java b/src/main/java/com/example/crud/entities/Product.java index 74ebff2..1de6713 100644 --- a/src/main/java/com/example/crud/entities/Product.java +++ b/src/main/java/com/example/crud/entities/Product.java @@ -40,9 +40,9 @@ public class Product extends AbstractAuditableEntity { /** * Seller of this product. - */ @ManyToOne(optional = false) private Person seller; + */ /** * Default constructor. diff --git a/src/main/java/com/example/crud/metrics/MetricsConfiguration.java b/src/main/java/com/example/crud/metrics/MetricsConfiguration.java index c73e013..e7397bd 100644 --- a/src/main/java/com/example/crud/metrics/MetricsConfiguration.java +++ b/src/main/java/com/example/crud/metrics/MetricsConfiguration.java @@ -7,13 +7,9 @@ import ch.qos.logback.core.joran.spi.JoranException; import com.codahale.metrics.*; import com.codahale.metrics.health.HealthCheckRegistry; import com.codahale.metrics.jvm.*; -import com.codahale.metrics.logback.InstrumentedAppender; import com.datastax.driver.core.Cluster; -import com.datastax.driver.core.Session; import com.ryantenney.metrics.spring.config.annotation.EnableMetrics; import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter; -import org.datanucleus.store.StoreManager; -import org.datanucleus.store.connection.ManagedConnection; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; @@ -21,7 +17,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; -import javax.persistence.EntityManagerFactory; import java.lang.management.ManagementFactory; import java.util.concurrent.TimeUnit; @@ -37,7 +32,7 @@ public class MetricsConfiguration extends MetricsConfigurerAdapter { private final Logger log = (Logger)LoggerFactory.getLogger(getClass().getName()); - private MetricRegistry metricRegistry = new MetricRegistry(); + private MetricRegistry metricRegistry = SharedMetricRegistries.getOrCreate("dunno"); private HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry(); diff --git a/src/main/java/com/example/crud/repositories/InventoryRepository.java b/src/main/java/com/example/crud/repositories/InventoryRepository.java index 9f429a4..37c76c6 100644 --- a/src/main/java/com/example/crud/repositories/InventoryRepository.java +++ b/src/main/java/com/example/crud/repositories/InventoryRepository.java @@ -1,5 +1,6 @@ package com.example.crud.repositories; +import com.datastax.driver.mapping.annotations.QueryParameters; import com.example.crud.entities.Inventory; import org.datanucleus.api.jpa.annotations.ReadOnly; import org.springframework.cache.annotation.CacheEvict; @@ -10,7 +11,6 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; -import java.beans.Transient; import java.util.List; //@Metrics(registry = "${this.registry}") @@ -19,7 +19,9 @@ public interface InventoryRepository extends JpaRepository, J //@Metered(name = "${this.id}") @Transactional @Cacheable(value = "inventory", key = "#name") - Inventory findByName(String name); + @QueryParameters(consistency="QUORUM") + //Query(value="select * from inventory where firstName = :name", nativeQuery=true) + Inventory findByName(@Param("name") String name); @ReadOnly @Query(value = "select * from inventory where product_id_eid contains :productId allow filtering", diff --git a/src/main/resources/META-INF/orm.xml b/src/main/resources/META-INF/orm.xml index cc57e2d..8fe0f79 100644 --- a/src/main/resources/META-INF/orm.xml +++ b/src/main/resources/META-INF/orm.xml @@ -46,7 +46,6 @@ - diff --git a/src/main/resources/ehcache.xml b/src/main/resources/ehcache.xml index 6dbcb6f..8ce4751 100644 --- a/src/main/resources/ehcache.xml +++ b/src/main/resources/ehcache.xml @@ -14,6 +14,8 @@ timeToLiveSeconds="600" overflowToDisk="true" transactionalMode="off"> + diff --git a/src/main/resources/jgroups-l2-cache-tcp-aws-native-s3.xml b/src/main/resources/jgroups-l2-cache-tcp-aws-native-s3.xml new file mode 100644 index 0000000..93c270d --- /dev/null +++ b/src/main/resources/jgroups-l2-cache-tcp-aws-native-s3.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml deleted file mode 100644 index 03e1e30..0000000 --- a/src/main/resources/logback.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - ${java-pattern} - - - TRACE - - - - - 10000 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 120000 index 0000000..e1cef24 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1 @@ +logback.xml_TRACE \ No newline at end of file diff --git a/src/main/resources/logback.xml_TRACE b/src/main/resources/logback.xml_TRACE new file mode 100644 index 0000000..1b3cfa4 --- /dev/null +++ b/src/main/resources/logback.xml_TRACE @@ -0,0 +1,74 @@ + + + + + + + + + + + + + ${java-pattern} + + + TRACE + + + + + 10000 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/logback.xml_WARN b/src/main/resources/logback.xml_WARN new file mode 100644 index 0000000..38d0717 --- /dev/null +++ b/src/main/resources/logback.xml_WARN @@ -0,0 +1,74 @@ + + + + + + + + + + + + + ${java-pattern} + + + TRACE + + + + + 10000 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +