You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by za...@apache.org on 2015/05/18 19:43:04 UTC
jclouds-labs git commit: JCLOUDS-826: Add skeleton and container
operations
Repository: jclouds-labs
Updated Branches:
refs/heads/master 969951d9b -> 83218e32d
JCLOUDS-826: Add skeleton and container operations
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/83218e32
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/83218e32
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/83218e32
Branch: refs/heads/master
Commit: 83218e32ddb8667f1752e552e64ea4887a5e9e7d
Parents: 969951d
Author: Roman Coedo <ro...@gmail.com>
Authored: Tue Apr 28 23:32:54 2015 +0200
Committer: Zack Shoylev <za...@rackspace.com>
Committed: Mon May 18 12:40:34 2015 -0500
----------------------------------------------------------------------
.gitignore | 1 +
jdbc/pom.xml | 149 ++++++++++++++
.../java/org/jclouds/jdbc/JdbcApiMetadata.java | 74 +++++++
.../org/jclouds/jdbc/config/JPAInitializer.java | 29 +++
.../jdbc/config/JdbcBlobStoreContextModule.java | 44 +++++
.../java/org/jclouds/jdbc/entity/Container.java | 120 ++++++++++++
.../validators/JdbcBlobKeyValidator.java | 38 ++++
.../validators/JdbcContainerNameValidator.java | 38 ++++
.../jdbc/repository/ContainerRepository.java | 50 +++++
.../jdbc/repository/GenericRepository.java | 55 ++++++
.../org/jclouds/jdbc/service/JdbcService.java | 69 +++++++
.../jdbc/strategy/JdbcStorageStrategy.java | 194 +++++++++++++++++++
.../org/jclouds/jdbc/util/JdbcBlobUtils.java | 70 +++++++
.../org/jclouds/jdbc/JdbcApiMetadataTest.java | 28 +++
.../org/jclouds/jdbc/JdbcBlobStoreTest.java | 72 +++++++
.../jclouds/jdbc/module/TestContextModule.java | 29 +++
.../jdbc/strategy/JdbcStorageStrategyTest.java | 101 ++++++++++
.../src/test/resources/META-INF/persistence.xml | 23 +++
jdbc/src/test/resources/log4j.properties | 25 +++
pom.xml | 1 +
20 files changed, 1210 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 50f3821..336ad47 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ atlassian-ide-plugin.xml
.java-version
*nb-configuration.xml
*nbactions.xml
+Makefile
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/pom.xml
----------------------------------------------------------------------
diff --git a/jdbc/pom.xml b/jdbc/pom.xml
new file mode 100644
index 0000000..6b00c10
--- /dev/null
+++ b/jdbc/pom.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.jclouds.labs</groupId>
+ <artifactId>jclouds-labs</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+ <groupId>org.apache.jclouds.labs</groupId>
+ <artifactId>jdbc</artifactId>
+ <name>jclouds jdbc core</name>
+ <description>jclouds components to access jdbc</description>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <!-- This api has been written in a manner which requires Java language level 7. -->
+ <maven.compile.source>1.6</maven.compile.source>
+ <maven.compile.target>1.6</maven.compile.target>
+ <jclouds.osgi.export>org.jclouds.jdbc*;version="${project.version}"</jclouds.osgi.export>
+ <jclouds.osgi.import>org.jclouds*;version="${project.version}",*</jclouds.osgi.import>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.jclouds</groupId>
+ <artifactId>jclouds-blobstore</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jclouds</groupId>
+ <artifactId>jclouds-core</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jclouds</groupId>
+ <artifactId>jclouds-blobstore</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jclouds.driver</groupId>
+ <artifactId>jclouds-log4j</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.auto.service</groupId>
+ <artifactId>auto-service</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject.extensions</groupId>
+ <artifactId>guice-persist</artifactId>
+ <version>4.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate.javax.persistence</groupId>
+ <artifactId>hibernate-jpa-2.1-api</artifactId>
+ <version>1.0.0.Final</version>
+ </dependency>
+
+
+ <!-- Test Dependencies -->
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-entitymanager</artifactId>
+ <version>4.3.9.Final</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>2.3.2</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>integration</id>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <threadCount>1</threadCount>
+ <excludes>
+ <exclude>**/*LiveTest.java</exclude>
+ <exclude>**/Base*Test.java</exclude>
+ </excludes>
+ <includes>
+ <include>**/*IntegrationTest.java</include>
+ </includes>
+ <systemPropertyVariables>
+ <jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
+ <jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
+ </systemPropertyVariables>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>animal-sniffer-maven-plugin</artifactId>
+ <configuration>
+ <signature>
+ <groupId>org.codehaus.mojo.signature</groupId>
+ <artifactId>java16</artifactId>
+ <version>1.0</version>
+ </signature>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
+
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/JdbcApiMetadata.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/JdbcApiMetadata.java b/jdbc/src/main/java/org/jclouds/jdbc/JdbcApiMetadata.java
new file mode 100644
index 0000000..b478505
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/JdbcApiMetadata.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc;
+
+import com.google.auto.service.AutoService;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+import org.jclouds.apis.ApiMetadata;
+import org.jclouds.apis.internal.BaseApiMetadata;
+import org.jclouds.blobstore.BlobStoreContext;
+import org.jclouds.jdbc.config.JdbcBlobStoreContextModule;
+
+import java.net.URI;
+
+/**
+ * Implementation of {@link ApiMetadata} for jclouds Jdbc BlobStore
+ */
+@AutoService(ApiMetadata.class)
+public class JdbcApiMetadata extends BaseApiMetadata {
+
+ @Override
+ public Builder toBuilder() {
+ return new Builder().fromApiMetadata(this);
+ }
+
+ public JdbcApiMetadata() {
+ super(new Builder());
+ }
+
+ protected JdbcApiMetadata(Builder builder) {
+ super(builder);
+ }
+
+ public static class Builder extends BaseApiMetadata.Builder<Builder> {
+
+ protected Builder() {
+ id("jdbc")
+ .name("Jdbc BlobStore")
+ .identityName("Unused")
+ .credentialName("unused")
+ .defaultEndpoint("http://localhost/transient")
+ .defaultIdentity("unused")
+ .defaultCredential("unused")
+ .version("1")
+ .documentation(URI.create("http://www.jclouds.org/documentation/userguide/blobstore-guide"))
+ .view(BlobStoreContext.class)
+ .defaultModules(ImmutableSet.<Class<? extends Module>>of(JdbcBlobStoreContextModule.class));
+ }
+
+ @Override
+ public JdbcApiMetadata build() {
+ return new JdbcApiMetadata(this);
+ }
+
+ @Override
+ protected Builder self() {
+ return this;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/config/JPAInitializer.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/config/JPAInitializer.java b/jdbc/src/main/java/org/jclouds/jdbc/config/JPAInitializer.java
new file mode 100644
index 0000000..60c14d4
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/config/JPAInitializer.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.config;
+
+import com.google.inject.Inject;
+import com.google.inject.persist.PersistService;
+
+public class JPAInitializer {
+
+ @Inject
+ private JPAInitializer(PersistService service) {
+ service.start();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/config/JdbcBlobStoreContextModule.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/config/JdbcBlobStoreContextModule.java b/jdbc/src/main/java/org/jclouds/jdbc/config/JdbcBlobStoreContextModule.java
new file mode 100644
index 0000000..3619eb6
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/config/JdbcBlobStoreContextModule.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.config;
+
+import com.google.inject.AbstractModule;
+import org.jclouds.blobstore.BlobRequestSigner;
+import org.jclouds.blobstore.BlobStore;
+import org.jclouds.blobstore.LocalBlobRequestSigner;
+import org.jclouds.blobstore.LocalStorageStrategy;
+import org.jclouds.blobstore.attr.ConsistencyModel;
+import org.jclouds.blobstore.config.BlobStoreObjectModule;
+import org.jclouds.blobstore.config.LocalBlobStore;
+import org.jclouds.blobstore.util.BlobUtils;
+import org.jclouds.jdbc.strategy.JdbcStorageStrategy;
+import org.jclouds.jdbc.util.JdbcBlobUtils;
+
+public class JdbcBlobStoreContextModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(JPAInitializer.class).asEagerSingleton();
+ bind(BlobStore.class).to(LocalBlobStore.class);
+ install(new BlobStoreObjectModule());
+ bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
+ bind(LocalStorageStrategy.class).to(JdbcStorageStrategy.class);
+ bind(BlobUtils.class).to(JdbcBlobUtils.class);
+ bind(BlobRequestSigner.class).to(LocalBlobRequestSigner.class);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/entity/Container.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/entity/Container.java b/jdbc/src/main/java/org/jclouds/jdbc/entity/Container.java
new file mode 100644
index 0000000..dd003a6
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/entity/Container.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.entity;
+
+import org.jclouds.blobstore.domain.ContainerAccess;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.PrePersist;
+import javax.persistence.Table;
+import java.util.Date;
+
+@Entity
+@Table
+public class Container {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(unique = true)
+ private String name;
+
+ private Date creationDate;
+
+ private ContainerAccess containerAccess;
+
+ public Container() {
+ }
+
+ public Container(Long id, String name, Date creationDate, ContainerAccess containerAccess) {
+ this.id = id;
+ this.name = name;
+ this.creationDate = creationDate;
+ this.containerAccess = containerAccess;
+ }
+
+ @PrePersist
+ private void defaults() {
+ this.creationDate = new Date();
+ if (containerAccess == null) {
+ this.containerAccess = ContainerAccess.PRIVATE;
+ }
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Date getCreationDate() {
+ return creationDate;
+ }
+
+ public void setCreationDate(Date creationDate) {
+ this.creationDate = creationDate;
+ }
+
+ public ContainerAccess getContainerAccess() {
+ return containerAccess;
+ }
+
+ public void setContainerAccess(ContainerAccess containerAccess) {
+ this.containerAccess = containerAccess;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String name;
+ private ContainerAccess containerAccess;
+
+ public Builder() {
+ }
+
+ public Builder name(String name){
+ this.name = name;
+ return this;
+ }
+
+ public Builder containerAccess(ContainerAccess containerAccess){
+ this.containerAccess = containerAccess;
+ return this;
+ }
+
+ public Container build() {
+ return new Container(null, name, null, containerAccess);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/predicates/validators/JdbcBlobKeyValidator.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/predicates/validators/JdbcBlobKeyValidator.java b/jdbc/src/main/java/org/jclouds/jdbc/predicates/validators/JdbcBlobKeyValidator.java
new file mode 100644
index 0000000..7cd5bda
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/predicates/validators/JdbcBlobKeyValidator.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.predicates.validators;
+
+import com.google.inject.Singleton;
+import org.jclouds.predicates.Validator;
+
+/**
+ * Validates name for jdbc container blob keys implementation
+ *
+ * @see org.jclouds.rest.InputParamValidator
+ * @see org.jclouds.predicates.Validator
+ */
+@Singleton
+public class JdbcBlobKeyValidator extends Validator<String> {
+
+ @Override
+ public void validate(String name) throws IllegalArgumentException {
+ //blob key cannot be null or empty
+ if (name == null || name.length() < 1)
+ throw new IllegalArgumentException("Blob key can't be null or empty");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/predicates/validators/JdbcContainerNameValidator.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/predicates/validators/JdbcContainerNameValidator.java b/jdbc/src/main/java/org/jclouds/jdbc/predicates/validators/JdbcContainerNameValidator.java
new file mode 100644
index 0000000..28d49ef
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/predicates/validators/JdbcContainerNameValidator.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.predicates.validators;
+
+import com.google.inject.Singleton;
+import org.jclouds.predicates.Validator;
+
+/**
+ * Validates container name for jdbc provider implementation
+ *
+ * @see org.jclouds.rest.InputParamValidator
+ * @see org.jclouds.predicates.Validator
+ */
+@Singleton
+public class JdbcContainerNameValidator extends Validator<String> {
+
+ @Override
+ public void validate(String name) throws IllegalArgumentException {
+ //container name cannot be null or empty
+ if (name == null || name.length() < 1)
+ throw new IllegalArgumentException("Container name can't be null or empty");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/repository/ContainerRepository.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/repository/ContainerRepository.java b/jdbc/src/main/java/org/jclouds/jdbc/repository/ContainerRepository.java
new file mode 100644
index 0000000..759be2b
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/repository/ContainerRepository.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.repository;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import org.jclouds.jdbc.entity.Container;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+@Singleton
+public class ContainerRepository extends GenericRepository<Container, Long> {
+
+ @Inject
+ private ContainerRepository(Provider<EntityManager> entityManager) {
+ super(entityManager);
+ }
+
+ public Container findContainerByName(String name) {
+ return entityManager.get().createQuery("SELECT c FROM " + entityClass.getName() + " c WHERE c.name = :name", entityClass)
+ .setParameter("name", name)
+ .getSingleResult();
+ }
+
+ public List<Container> findAllContainers() {
+ return entityManager.get().createQuery("SELECT c FROM " + entityClass.getName() + " c", entityClass)
+ .getResultList();
+ }
+
+ public void deleteContainerByName(String name) {
+ delete(findContainerByName(name));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/repository/GenericRepository.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/repository/GenericRepository.java b/jdbc/src/main/java/org/jclouds/jdbc/repository/GenericRepository.java
new file mode 100644
index 0000000..58964a8
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/repository/GenericRepository.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.repository;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import javax.persistence.EntityManager;
+import java.io.Serializable;
+import java.lang.reflect.ParameterizedType;
+
+public abstract class GenericRepository<T, PK extends Serializable> {
+
+ protected final Class<T> entityClass;
+ protected final Provider<EntityManager> entityManager;
+
+ @Inject
+ @SuppressWarnings("unchecked")
+ protected GenericRepository(Provider<EntityManager> entityManager) {
+ this.entityManager = entityManager;
+ this.entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
+ }
+
+ public T create(T entity) {
+ entityManager.get().persist(entity);
+ return entity;
+ }
+
+ public T find(PK id) {
+ return entityManager.get().find(entityClass, id);
+ }
+
+ public T save(T entity) {
+ return entityManager.get().merge(entity);
+ }
+
+ public void delete(T entity) {
+ entityManager.get().remove(entityManager.get().contains(entity) ? entity : entityManager.get().merge(entity));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/service/JdbcService.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/service/JdbcService.java b/jdbc/src/main/java/org/jclouds/jdbc/service/JdbcService.java
new file mode 100644
index 0000000..08990ba
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/service/JdbcService.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.service;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
+import org.jclouds.blobstore.domain.ContainerAccess;
+import org.jclouds.jdbc.entity.Container;
+import org.jclouds.jdbc.repository.ContainerRepository;
+
+import java.util.List;
+
+@Singleton
+public class JdbcService {
+
+ private final ContainerRepository containerRepository;
+
+ @Inject
+ JdbcService(ContainerRepository containerRepository) {
+ this.containerRepository = containerRepository;
+ }
+
+ @Transactional
+ public void createContainer(String name, ContainerAccess access) {
+ containerRepository.create(Container.builder().name(name).containerAccess(access).build());
+ }
+
+ @Transactional
+ public void createContainer(String name) {
+ containerRepository.create(Container.builder().name(name).build());
+ }
+
+ @Transactional
+ public List<Container> findAllContainers() {
+ return containerRepository.findAllContainers();
+ }
+
+ @Transactional
+ public Container findContainerByName(String name) {
+ return containerRepository.findContainerByName(name);
+ }
+
+ @Transactional
+ public void deleteContainerByName(String name) {
+ containerRepository.deleteContainerByName(name);
+ }
+
+ @Transactional
+ public void setContainerAccessByName(String name, ContainerAccess access) {
+ Container container = containerRepository.findContainerByName(name);
+ container.setContainerAccess(access);
+ containerRepository.save(container);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/strategy/JdbcStorageStrategy.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/strategy/JdbcStorageStrategy.java b/jdbc/src/main/java/org/jclouds/jdbc/strategy/JdbcStorageStrategy.java
new file mode 100644
index 0000000..5fb2032
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/strategy/JdbcStorageStrategy.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.strategy;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.persist.Transactional;
+import org.jclouds.blobstore.LocalStorageStrategy;
+import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.blobstore.domain.BlobAccess;
+import org.jclouds.blobstore.domain.BlobBuilder;
+import org.jclouds.blobstore.domain.ContainerAccess;
+import org.jclouds.blobstore.domain.MutableStorageMetadata;
+import org.jclouds.blobstore.domain.StorageMetadata;
+import org.jclouds.blobstore.domain.StorageType;
+import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
+import org.jclouds.blobstore.options.CreateContainerOptions;
+import org.jclouds.blobstore.options.ListContainerOptions;
+import org.jclouds.domain.Location;
+import org.jclouds.jdbc.entity.Container;
+import org.jclouds.jdbc.predicates.validators.JdbcBlobKeyValidator;
+import org.jclouds.jdbc.predicates.validators.JdbcContainerNameValidator;
+import org.jclouds.jdbc.service.JdbcService;
+import org.jclouds.logging.Logger;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.persistence.NoResultException;
+import javax.persistence.PersistenceException;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * JdbcStorageStrategy implements a blob store that stores objects
+ * on a jdbc supported database. Content metadata and user attributes are stored in
+ * the database as well.
+ */
+public class JdbcStorageStrategy implements LocalStorageStrategy {
+
+ @Resource
+ private Logger logger = Logger.NULL;
+
+ private final Provider<BlobBuilder> blobBuilders;
+ private final JdbcService jdbcService;
+ private final JdbcContainerNameValidator jdbcContainerNameValidator;
+ private final JdbcBlobKeyValidator jdbcBlobKeyValidator;
+
+ @Inject
+ JdbcStorageStrategy(Provider<BlobBuilder> blobBuilders,
+ JdbcContainerNameValidator jdbcContainerNameValidator, JdbcBlobKeyValidator jdbcBlobKeyValidator,
+ JdbcService jdbcService)
+ throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException {
+ this.jdbcService = jdbcService;
+ this.blobBuilders = blobBuilders;
+ this.jdbcContainerNameValidator = jdbcContainerNameValidator;
+ this.jdbcBlobKeyValidator = jdbcBlobKeyValidator;
+ }
+
+ @Override
+ public boolean containerExists(String container) {
+ jdbcContainerNameValidator.validate(container);
+ try {
+ jdbcService.findContainerByName(container);
+ } catch (NoResultException e) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public Iterable<String> getAllContainerNames() {
+ List<Container> containers = jdbcService.findAllContainers();
+ ImmutableList.Builder<String> result = ImmutableList.builder();
+ for (Container c : containers) {
+ result.add(c.getName());
+ }
+ return result.build();
+ }
+
+ @Override
+ public boolean createContainerInLocation(String container, Location location,
+ CreateContainerOptions createContainerOptions) {
+ logger.debug("Creating container %s", container);
+ ContainerAccess containerAccess = createContainerOptions == null ? ContainerAccess.PRIVATE
+ : (createContainerOptions.isPublicRead() ? ContainerAccess.PUBLIC_READ
+ : ContainerAccess.PRIVATE);
+ try {
+ jdbcContainerNameValidator.validate(container);
+ jdbcService.createContainer(container, containerAccess);
+ } catch (PersistenceException e) {
+ return false;
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public ContainerAccess getContainerAccess(String container) {
+ return jdbcService.findContainerByName(container).getContainerAccess();
+ }
+
+ @Override
+ public void setContainerAccess(String container, ContainerAccess containerAccess) {
+ jdbcService.setContainerAccessByName(container, containerAccess);
+ }
+
+ @Override
+ public void deleteContainer(String container) {
+ jdbcContainerNameValidator.validate(container);
+ jdbcService.deleteContainerByName(container);
+ }
+
+ @Override
+ public void clearContainer(String s) {
+
+ }
+
+ @Override
+ public void clearContainer(String s, ListContainerOptions listContainerOptions) {
+
+ }
+
+ @Override
+ @Transactional
+ public StorageMetadata getContainerMetadata(String container) {
+ MutableStorageMetadata metadata = new MutableStorageMetadataImpl();
+ metadata.setName(container);
+ metadata.setType(StorageType.CONTAINER);
+ metadata.setLocation(null);
+ metadata.setCreationDate(jdbcService.findContainerByName(container).getCreationDate());
+ return metadata;
+ }
+
+ @Override
+ public boolean blobExists(String s, String s1) {
+ return false;
+ }
+
+ @Override
+ public Iterable<String> getBlobKeysInsideContainer(String s) throws IOException {
+ return null;
+ }
+
+ @Override
+ public Blob getBlob(String s, String s1) {
+ return null;
+ }
+
+ @Override
+ public String putBlob(String s, Blob blob) throws IOException {
+ return null;
+ }
+
+ @Override
+ public void removeBlob(String s, String s1) {
+
+ }
+
+ @Override
+ public BlobAccess getBlobAccess(String s, String s1) {
+ return null;
+ }
+
+ @Override
+ public void setBlobAccess(String s, String s1, BlobAccess blobAccess) {
+
+ }
+
+ @Override
+ public Location getLocation(String name) {
+ return null;
+ }
+
+ @Override
+ public String getSeparator() {
+ return "/";
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/main/java/org/jclouds/jdbc/util/JdbcBlobUtils.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/jclouds/jdbc/util/JdbcBlobUtils.java b/jdbc/src/main/java/org/jclouds/jdbc/util/JdbcBlobUtils.java
new file mode 100644
index 0000000..dda6e01
--- /dev/null
+++ b/jdbc/src/main/java/org/jclouds/jdbc/util/JdbcBlobUtils.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.util;
+
+import javax.inject.Provider;
+
+import org.jclouds.blobstore.LocalStorageStrategy;
+import org.jclouds.blobstore.domain.BlobBuilder;
+import org.jclouds.blobstore.options.ListContainerOptions;
+import org.jclouds.blobstore.util.BlobUtils;
+import org.jclouds.jdbc.strategy.JdbcStorageStrategy;
+
+import com.google.inject.Inject;
+
+/**
+ * Implements the {@link BlobUtils} interfaced and act as a bridge to
+ * {@link LocalStorageStrategy} when used inside {@link BlobStore}
+ */
+public class JdbcBlobUtils implements BlobUtils {
+
+ protected final JdbcStorageStrategy storageStrategy;
+ protected final Provider<BlobBuilder> blobBuilders;
+
+ @Inject
+ JdbcBlobUtils(LocalStorageStrategy storageStrategy, Provider<BlobBuilder> blobBuilders) {
+ this.storageStrategy = (JdbcStorageStrategy) storageStrategy;
+ this.blobBuilders = blobBuilders;
+ }
+
+ @Override
+ public BlobBuilder blobBuilder() {
+ return blobBuilders.get();
+ }
+
+ @Override public boolean directoryExists(String s, String s1) {
+ return false;
+ }
+
+ @Override public void createDirectory(String s, String s1) {
+
+ }
+
+ @Override public long countBlobs(String s, ListContainerOptions listContainerOptions) {
+ return 0;
+ }
+
+ @Override
+ public void clearContainer(String container, ListContainerOptions options) {
+ storageStrategy.clearContainer(container, options);
+ }
+
+ @Override public void deleteDirectory(String s, String s1) {
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/test/java/org/jclouds/jdbc/JdbcApiMetadataTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/jclouds/jdbc/JdbcApiMetadataTest.java b/jdbc/src/test/java/org/jclouds/jdbc/JdbcApiMetadataTest.java
new file mode 100644
index 0000000..036612d
--- /dev/null
+++ b/jdbc/src/test/java/org/jclouds/jdbc/JdbcApiMetadataTest.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc;
+
+import org.jclouds.blobstore.internal.BaseBlobStoreApiMetadataTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "JdbcApiMetadataTest")
+public class JdbcApiMetadataTest extends BaseBlobStoreApiMetadataTest {
+
+ public JdbcApiMetadataTest() {
+ super(new JdbcApiMetadata());
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/test/java/org/jclouds/jdbc/JdbcBlobStoreTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/jclouds/jdbc/JdbcBlobStoreTest.java b/jdbc/src/test/java/org/jclouds/jdbc/JdbcBlobStoreTest.java
new file mode 100644
index 0000000..270adca
--- /dev/null
+++ b/jdbc/src/test/java/org/jclouds/jdbc/JdbcBlobStoreTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+import com.google.inject.persist.jpa.JpaPersistModule;
+import org.jclouds.ContextBuilder;
+import org.jclouds.blobstore.BlobStore;
+import org.jclouds.blobstore.BlobStoreContext;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Set;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@Test(groups = "unit", testName = "JdbcBlobStoreTest", singleThreaded = true)
+public class JdbcBlobStoreTest {
+
+ private static final String CONTAINER_NAME = "test-container";
+ private static final Set<Module> MODULES = ImmutableSet.<Module> of(new JpaPersistModule("jclouds-test"));
+
+ private static final String PROVIDER = "jdbc";
+
+ private BlobStoreContext context = null;
+ private BlobStore blobStore = null;
+
+ @BeforeMethod
+ protected void setUp() throws Exception {
+ context = ContextBuilder.newBuilder(PROVIDER)
+ .modules(MODULES)
+ .build(BlobStoreContext.class);
+ blobStore = context.getBlobStore();
+ }
+
+ @AfterMethod
+ protected void tearDown() throws IOException {
+ context.close();
+ }
+
+ @Test
+ public void testCreateContainerInLocation() {
+ assertThat(blobStore.createContainerInLocation(null, CONTAINER_NAME)).isTrue();
+ assertThat(blobStore.containerExists(CONTAINER_NAME)).isTrue();
+ }
+
+ @Test
+ public void testDeleteContainer() {
+ assertThat(blobStore.createContainerInLocation(null, CONTAINER_NAME)).isTrue();
+ assertThat(blobStore.containerExists(CONTAINER_NAME)).isTrue();
+ blobStore.deleteContainer(CONTAINER_NAME);
+ assertThat(blobStore.containerExists(CONTAINER_NAME)).isFalse();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/test/java/org/jclouds/jdbc/module/TestContextModule.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/jclouds/jdbc/module/TestContextModule.java b/jdbc/src/test/java/org/jclouds/jdbc/module/TestContextModule.java
new file mode 100644
index 0000000..0798813
--- /dev/null
+++ b/jdbc/src/test/java/org/jclouds/jdbc/module/TestContextModule.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.module;
+
+import com.google.inject.AbstractModule;
+import org.jclouds.jdbc.config.JPAInitializer;
+
+public class TestContextModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(JPAInitializer.class).asEagerSingleton();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/test/java/org/jclouds/jdbc/strategy/JdbcStorageStrategyTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/jclouds/jdbc/strategy/JdbcStorageStrategyTest.java b/jdbc/src/test/java/org/jclouds/jdbc/strategy/JdbcStorageStrategyTest.java
new file mode 100644
index 0000000..ef72f61
--- /dev/null
+++ b/jdbc/src/test/java/org/jclouds/jdbc/strategy/JdbcStorageStrategyTest.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.jdbc.strategy;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Guice;
+import com.google.inject.Module;
+import com.google.inject.persist.jpa.JpaPersistModule;
+import org.jclouds.blobstore.domain.ContainerAccess;
+import org.jclouds.blobstore.domain.StorageMetadata;
+import org.jclouds.blobstore.domain.StorageType;
+import org.jclouds.blobstore.options.CreateContainerOptions;
+import org.jclouds.jdbc.module.TestContextModule;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Date;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@Test(groups = "unit", testName = "JdbcStorageStrategyTest", singleThreaded = true)
+public class JdbcStorageStrategyTest {
+
+ private static final String CONTAINER_NAME = "jclouds-test";
+ private JdbcStorageStrategy storageStrategy;
+
+ @BeforeMethod
+ protected void setUp() throws Exception {
+ storageStrategy = Guice.createInjector(ImmutableSet.<Module> of(new TestContextModule(), new JpaPersistModule("jclouds-test"))).getInstance(JdbcStorageStrategy.class);
+ }
+
+ @Test
+ public void testCreateContainerInLocation() {
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME, null, null)).isTrue();
+ assertThat(storageStrategy.containerExists(CONTAINER_NAME)).isTrue();
+ }
+
+ @Test
+ public void testCreateDuplicateContainerInLocation() {
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME, null, null)).isTrue();
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME, null, null)).isFalse();
+ }
+
+ @Test
+ public void testDefaultContainerAccess() {
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME, null, null)).isTrue();
+ assertThat(storageStrategy.getContainerAccess(CONTAINER_NAME)).isEqualTo(ContainerAccess.PRIVATE);
+ }
+
+ @Test
+ public void testOverridedPublicContainerAccess() {
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME, null, new CreateContainerOptions().publicRead())).isTrue();
+ assertThat(storageStrategy.getContainerAccess(CONTAINER_NAME)).isEqualTo(ContainerAccess.PUBLIC_READ);
+ }
+
+ @Test
+ public void testOverridedPrivateContainerAccess() {
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME, null, CreateContainerOptions.NONE)).isTrue();
+ assertThat(storageStrategy.getContainerAccess(CONTAINER_NAME)).isEqualTo(ContainerAccess.PRIVATE);
+ }
+
+ @Test
+ public void testDeleteContainer() {
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME, null, null)).isTrue();
+ assertThat(storageStrategy.containerExists(CONTAINER_NAME)).isTrue();
+ storageStrategy.deleteContainer(CONTAINER_NAME);
+ assertThat(storageStrategy.containerExists(CONTAINER_NAME)).isFalse();
+ }
+
+ @Test
+ public void testGetAllContainerNames() {
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME + "1", null, null)).isTrue();
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME + "2", null, null)).isTrue();
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME + "3", null, null)).isTrue();
+ assertThat(storageStrategy.getAllContainerNames()).containsExactly(CONTAINER_NAME + "1", CONTAINER_NAME + "2", CONTAINER_NAME + "3");
+ }
+
+ @Test
+ public void testGetContainerMetadata() {
+ assertThat(storageStrategy.createContainerInLocation(CONTAINER_NAME, null, null)).isTrue();
+ StorageMetadata storageMetadata = storageStrategy.getContainerMetadata(CONTAINER_NAME);
+ assertThat(storageMetadata.getName()).isEqualTo(CONTAINER_NAME);
+ assertThat(storageMetadata.getType()).isEqualTo(StorageType.CONTAINER);
+ assertThat(storageMetadata.getCreationDate()).isBefore(new Date());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/test/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/jdbc/src/test/resources/META-INF/persistence.xml b/jdbc/src/test/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..11b870e
--- /dev/null
+++ b/jdbc/src/test/resources/META-INF/persistence.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+ version="1.0">
+ <persistence-unit name="jclouds-test" transaction-type="RESOURCE_LOCAL">
+ <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
+
+ <class>org.jclouds.jdbc.entity.Container</class>
+ <exclude-unlisted-classes>true</exclude-unlisted-classes>
+
+ <properties>
+ <property name="hibernate.archive.autodetection" value="class" />
+ <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
+ <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
+ <property name="hibernate.connection.url" value="jdbc:hsqldb:file:target/testdb;shutdown=true" />
+ <property name="hibernate.connection.user" value="sa" />
+ <!-- <property name="hibernate.show_sql" value="true"/> -->
+ <property name="hibernate.flushMode" value="FLUSH_AUTO" />
+ <property name="hibernate.hbm2ddl.auto" value="create" />
+ </properties>
+ </persistence-unit>
+</persistence>
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/jdbc/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/jdbc/src/test/resources/log4j.properties b/jdbc/src/test/resources/log4j.properties
new file mode 100644
index 0000000..0815baa
--- /dev/null
+++ b/jdbc/src/test/resources/log4j.properties
@@ -0,0 +1,25 @@
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#
+log4j.rootLogger=WARN, A1
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+log4j.logger.org.hibernate = ERROR
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/83218e32/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index b5265bf..b632662 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,6 +75,7 @@
<module>cloudsigma2-wdc</module>
<module>cloudsigma2-zrh</module>
<module>digitalocean</module>
+ <module>jdbc</module>
<module>joyent-cloudapi</module>
<module>joyentcloud</module>
<module>abiquo</module>