diff --git a/engine/pom.xml b/engine/pom.xml
index 38c1d6b8dac..1a8a0b8e5b3 100644
--- a/engine/pom.xml
+++ b/engine/pom.xml
@@ -39,6 +39,7 @@
storage
storage/volume
storage/image
+ storage/imagemotion
storage/backup
storage/snapshot
storage/integration-test
diff --git a/engine/storage/imagemotion/pom.xml b/engine/storage/imagemotion/pom.xml
new file mode 100644
index 00000000000..856b9d995e5
--- /dev/null
+++ b/engine/storage/imagemotion/pom.xml
@@ -0,0 +1,62 @@
+
+
+ 4.0.0
+ cloud-engine-storage-imagemotion
+ Apache CloudStack Engine Storage Image Motion Component
+
+ org.apache.cloudstack
+ cloud-engine
+ 4.1.0-SNAPSHOT
+ ../../pom.xml
+
+
+
+ org.apache.cloudstack
+ cloud-engine-storage
+ ${project.version}
+
+
+ org.apache.cloudstack
+ cloud-engine-storage-volume
+ ${project.version}
+ runtime
+
+
+ org.apache.cloudstack
+ cloud-engine-storage-image
+ ${project.version}
+ runtime
+
+
+ mysql
+ mysql-connector-java
+ ${cs.mysql.version}
+ provided
+
+
+ org.mockito
+ mockito-all
+ 1.9.5
+
+
+ javax.inject
+ javax.inject
+ 1
+
+
+
+ install
+ src
+ test
+
+
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java
similarity index 100%
rename from engine/storage/image/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java
rename to engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java
similarity index 89%
rename from engine/storage/image/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java
rename to engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java
index 3cf5efc6f69..85db4dcff20 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java
+++ b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java
@@ -22,11 +22,7 @@ import java.util.List;
import javax.inject.Inject;
-import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.image.ImageService;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java
similarity index 100%
rename from engine/storage/image/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java
rename to engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java
diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml
index 62e37a22fa6..c2f4d24d183 100644
--- a/engine/storage/integration-test/pom.xml
+++ b/engine/storage/integration-test/pom.xml
@@ -38,6 +38,12 @@
${project.version}
test
+
+ org.apache.cloudstack
+ cloud-engine-storage-imagemotion
+ ${project.version}
+ test
+
mysql
mysql-connector-java
diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml
index 4a1f9f67adb..b214201851e 100644
--- a/engine/storage/pom.xml
+++ b/engine/storage/pom.xml
@@ -66,15 +66,5 @@
install
src
test
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 2.12.4
-
- true
-
-
-
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageService.java b/engine/storage/src/org/apache/cloudstack/storage/image/ImageService.java
similarity index 100%
rename from engine/storage/image/src/org/apache/cloudstack/storage/image/ImageService.java
rename to engine/storage/src/org/apache/cloudstack/storage/image/ImageService.java
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java
index bd7c878230a..cb2e674db67 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java
@@ -23,7 +23,7 @@ public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProv
private final String providerName = "default primary data store provider";
protected PrimaryDataStoreDriver driver;
private PrimaryDataStoreProviderVO provider;
- private final PrimaryDataStoreDao dataStoreDao;
+ protected final PrimaryDataStoreDao dataStoreDao;
protected PrimaryDataStoreLifeCycle dataStoreLifeCycle;
@Inject
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index 0e6ed9f425e..edb661a8769 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -35,6 +35,7 @@ import org.apache.cloudstack.storage.image.motion.ImageMotionService;
import org.apache.cloudstack.storage.volume.db.VolumeDao;
import org.apache.cloudstack.storage.volume.db.VolumeVO;
+import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
@@ -45,7 +46,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
//1. change volume state
//2. orchestrator of volume, control most of the information of volume, storage pool id, voluem state, scope etc.
-@Service
+@Component
public class VolumeServiceImpl implements VolumeService {
@Inject
VolumeDao volDao;
diff --git a/plugins/pom.xml b/plugins/pom.xml
index dbdea24e17b..a55289f06a1 100644
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -45,6 +45,8 @@
user-authenticators/ldap
user-authenticators/md5
user-authenticators/plain-text
+ storage/volume/solidfire
+ storage/image/s3
diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml
new file mode 100644
index 00000000000..4ea6517527b
--- /dev/null
+++ b/plugins/storage/image/s3/pom.xml
@@ -0,0 +1,41 @@
+
+
+ 4.0.0
+ cloud-plugin-storage-image-s3
+ Apache CloudStack Plugin - Storage Image S3
+
+ org.apache.cloudstack
+ cloudstack-plugins
+ 4.1.0-SNAPSHOT
+ ../../../pom.xml
+
+
+
+ org.apache.cloudstack
+ cloud-engine-storage-image
+ ${project.version}
+
+
+
+ install
+ src
+ test
+
+
diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml
new file mode 100644
index 00000000000..e3da9ea8621
--- /dev/null
+++ b/plugins/storage/volume/solidfire/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+ cloud-plugin-storage-volume-solidfire
+ Apache CloudStack Plugin - Storage Volume solidfire
+
+ org.apache.cloudstack
+ cloudstack-plugins
+ 4.1.0-SNAPSHOT
+ ../../../pom.xml
+
+
+
+ org.apache.cloudstack
+ cloud-engine-storage-volume
+ ${project.version}
+
+
+ mysql
+ mysql-connector-java
+ ${cs.mysql.version}
+ provided
+
+
+
+ install
+ src
+ test
+
+
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
new file mode 100644
index 00000000000..136bec10eff
--- /dev/null
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
@@ -0,0 +1,40 @@
+package org.apache.cloudstack.storage.datastore.driver;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
+import org.apache.cloudstack.storage.volume.VolumeObject;
+
+public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
+
+ @Override
+ public boolean createVolume(VolumeObject vol) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean createVolumeFromBaseImage(VolumeObject volume,
+ TemplateOnPrimaryDataStoreInfo template) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean deleteVolume(VolumeObject vo) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public String grantAccess(VolumeObject vol, EndPoint ep) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean revokeAccess(VolumeObject vol, EndPoint ep) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+}
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java
new file mode 100644
index 00000000000..ef63423aaed
--- /dev/null
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java
@@ -0,0 +1,43 @@
+package org.apache.cloudstack.storage.datastore.provider;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.storage.datastore.DefaultPrimaryDataStoreImpl;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO;
+import org.apache.cloudstack.storage.datastore.driver.SolidfirePrimaryDataStoreDriver;
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.component.ComponentInject;
+
+@Component
+public class SolidfirePrimaryDataStoreProvider extends
+ DefaultPrimaryDatastoreProviderImpl {
+ private final String name = "Solidfre Primary Data Store Provider";
+ private SolidfirePrimaryDataStoreDriver driver;
+
+ @Inject
+ public SolidfirePrimaryDataStoreProvider(PrimaryDataStoreDao dataStoreDao) {
+ super(dataStoreDao);
+ driver = new SolidfirePrimaryDataStoreDriver();
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public PrimaryDataStore getDataStore(long dataStoreId) {
+ PrimaryDataStoreVO dsv = dataStoreDao.findById(dataStoreId);
+ if (dsv == null) {
+ return null;
+ }
+
+ PrimaryDataStore pds = new DefaultPrimaryDataStoreImpl(driver, dsv, null);
+ pds = ComponentInject.inject(pds);
+ return pds;
+ }
+}
diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java
new file mode 100644
index 00000000000..ba356e3e6b5
--- /dev/null
+++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java
@@ -0,0 +1,18 @@
+package org.apache.cloudstack.storage.test;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+
+import com.cloud.utils.db.Transaction;
+
+public class AopTestAdvice {
+ public Object AopTestMethod(ProceedingJoinPoint call) throws Throwable {
+ Transaction txn = Transaction.open(call.getSignature().getName());
+ Object ret = null;
+ try {
+ ret = call.proceed();
+ } finally {
+ txn.close();
+ }
+ return ret;
+ }
+}
diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
new file mode 100644
index 00000000000..6a7b5ad16b1
--- /dev/null
+++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
@@ -0,0 +1,35 @@
+package org.apache.cloudstack.storage.test;
+
+import org.apache.cloudstack.storage.image.motion.ImageMotionService;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.host.dao.HostDao;
+
+public class ChildTestConfiguration extends TestConfiguration {
+
+ @Override
+ @Bean
+ public HostDao hostDao() {
+ HostDao dao = super.hostDao();
+ HostDao nDao = Mockito.spy(dao);
+ return nDao;
+ }
+
+ @Bean
+ public AgentManager agentMgr() {
+ return Mockito.mock(AgentManager.class);
+ }
+
+ @Bean
+ public ImageMotionService imageMotion() {
+ return Mockito.mock(ImageMotionService.class);
+ }
+
+/* @Override
+ @Bean
+ public PrimaryDataStoreDao primaryDataStoreDao() {
+ return Mockito.mock(PrimaryDataStoreDaoImpl.class);
+ }*/
+}
diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/TestConfiguration.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/TestConfiguration.java
new file mode 100644
index 00000000000..42cd8fb5f59
--- /dev/null
+++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/TestConfiguration.java
@@ -0,0 +1,21 @@
+package org.apache.cloudstack.storage.test;
+
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDaoImpl;
+
+@Configuration
+public class TestConfiguration {
+ @Bean
+ public HostDao hostDao() {
+ return new HostDaoImpl();
+ }
+ @Bean
+ public PrimaryDataStoreDao primaryDataStoreDao() {
+ return new PrimaryDataStoreDaoImpl();
+ }
+}
diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java
new file mode 100644
index 00000000000..39ecc0c1029
--- /dev/null
+++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java
@@ -0,0 +1,140 @@
+package org.apache.cloudstack.storage.test;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.storage.command.CreateVolumeAnswer;
+import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.lifecycle.PrimaryDataStoreLifeCycle;
+import org.apache.cloudstack.storage.datastore.provider.PrimaryDataStoreProvider;
+import org.apache.cloudstack.storage.datastore.provider.PrimaryDataStoreProviderManager;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.org.Cluster.ClusterType;
+import com.cloud.org.Managed.ManagedState;
+import com.cloud.resource.ResourceState;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations="classpath:/resource/storageContext.xml")
+public class VolumeTest {
+ @Inject
+ HostDao hostDao;
+ @Inject
+ HostPodDao podDao;
+ @Inject
+ ClusterDao clusterDao;
+ @Inject
+ DataCenterDao dcDao;
+ @Inject
+ PrimaryDataStoreDao primaryStoreDao;
+ @Inject
+ PrimaryDataStoreProviderManager primaryDataStoreProviderMgr;
+ @Inject
+ AgentManager agentMgr;
+ Long dcId;
+ Long clusterId;
+ @Before
+ public void setUp() {
+ //create data center
+ DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24",
+ null, null, NetworkType.Basic, null, null, true, true);
+ dc = dcDao.persist(dc);
+ dcId = dc.getId();
+ //create pod
+
+ HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "192.168.56.1", "192.168.56.0/24", 8, "test");
+ pod = podDao.persist(pod);
+ //create xen cluster
+ ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
+ cluster.setHypervisorType(HypervisorType.XenServer.toString());
+ cluster.setClusterType(ClusterType.CloudManaged);
+ cluster.setManagedState(ManagedState.Managed);
+ cluster = clusterDao.persist(cluster);
+ clusterId = cluster.getId();
+ //create xen host
+
+ HostVO host = new HostVO(UUID.randomUUID().toString());
+ host.setName("devcloud xen host");
+ host.setType(Host.Type.Routing);
+ host.setPrivateIpAddress("192.168.56.2");
+ host.setDataCenterId(dc.getId());
+ host.setVersion("6.0.1");
+ host.setAvailable(true);
+ host.setSetup(true);
+ host.setLastPinged(0);
+ host.setResourceState(ResourceState.Enabled);
+ host.setClusterId(cluster.getId());
+
+ host = hostDao.persist(host);
+ List results = new ArrayList();
+ results.add(host);
+ Mockito.when(hostDao.listAll()).thenReturn(results);
+ Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results);
+ CreateVolumeAnswer createVolumeFromImageAnswer = new CreateVolumeAnswer(UUID.randomUUID().toString());
+
+ try {
+ Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(CreateVolumeFromBaseImageCommand.class))).thenReturn(createVolumeFromImageAnswer);
+ } catch (AgentUnavailableException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (OperationTimedoutException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+ //Mockito.when(primaryStoreDao.findById(Mockito.anyLong())).thenReturn(primaryStore);
+ }
+
+ private PrimaryDataStoreInfo createPrimaryDataStore() {
+ try {
+ primaryDataStoreProviderMgr.configure("primary data store mgr", new HashMap());
+ PrimaryDataStoreProvider provider = primaryDataStoreProviderMgr.getDataStoreProvider("Solidfre Primary Data Store Provider");
+ PrimaryDataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+ Map params = new HashMap();
+ params.put("url", "nfs://test/test");
+ params.put("dcId", dcId.toString());
+ params.put("clusterId", clusterId.toString());
+ params.put("name", "my primary data store");
+ PrimaryDataStoreInfo primaryDataStoreInfo = lifeCycle.registerDataStore(params);
+ return primaryDataStoreInfo;
+ } catch (ConfigurationException e) {
+ return null;
+ }
+ }
+
+ @Test
+ public void createPrimaryDataStoreTest() {
+ createPrimaryDataStore();
+ }
+}
\ No newline at end of file
diff --git a/plugins/storage/volume/solidfire/test/resource/storageContext.xml b/plugins/storage/volume/solidfire/test/resource/storageContext.xml
new file mode 100644
index 00000000000..6800d8f48b8
--- /dev/null
+++ b/plugins/storage/volume/solidfire/test/resource/storageContext.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+