Author: jawi Date: Mon Sep 30 12:00:26 2013 New Revision: 1527522 URL: http://svn.apache.org/r1527522 Log: ACE-384 - add size estimation for DP: - when an artifact is added to a repository, it size is stored as well; - when a deployment is defined for a target, the sizes of all included artifacts are included as well; - the DeploymentServlet now also responds to a HEAD request, in which it calculates an estimation of the deployment package (= size of all included artifacts + an additional factor to compensate for deviations caused by RPs); - added some basic unit and integration tests. Modified: ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/StatefulTargetRepositoryTest.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ArtifactResource.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactObjectImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/DeploymentVersionRepository.java ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/bundle/impl/BundleHelperTest.java ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/configuration/impl/ConfigurationHelperImplTest.java ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/impl/ArtifactTest.java ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/impl/ModelTest.java ace/trunk/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java ace/trunk/org.apache.ace.deployment/bnd.bnd ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/provider/ArtifactData.java ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/provider/filebased/FileBasedProvider.java ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/provider/impl/ArtifactDataImpl.java ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/provider/repositorybased/BaseRepositoryHandler.java ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/provider/repositorybased/RepositoryBasedProvider.java ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/DeploymentServlet.java ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/TestData.java ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/DeploymentTest.java ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/filebased/FileBasedProviderTest.java ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/RepositoryBasedProviderTest.java ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/servlet/DeploymentServletTest.java ace/trunk/org.apache.ace.obr/test/org/apache/ace/obr/metadata/bindeximpl/BindexMetadataTest.java Modified: ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java (original) +++ ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/BaseRepositoryAdminTest.java Mon Sep 30 12:00:26 2013 @@ -85,7 +85,7 @@ public abstract class BaseRepositoryAdmi m_name = String.format("user-%s", Long.toHexString(System.nanoTime())); } - public Dictionary getCredentials() { + public Dictionary getCredentials() { return new Properties(); } @@ -93,7 +93,7 @@ public abstract class BaseRepositoryAdmi return m_name; } - public Dictionary getProperties() { + public Dictionary getProperties() { return new Properties(); } @@ -237,11 +237,14 @@ public abstract class BaseRepositoryAdmi } protected ArtifactObject createBasicBundleObject(String symbolicName, String version, String processorPID) { + return createBasicBundleObject(symbolicName, version, processorPID, null); + } + + protected ArtifactObject createBasicBundleObject(String symbolicName, String version, String processorPID, String size) { Map attr = new HashMap(); attr.put(BundleHelper.KEY_SYMBOLICNAME, symbolicName); attr.put(ArtifactObject.KEY_MIMETYPE, BundleHelper.MIMETYPE); attr.put(ArtifactObject.KEY_URL, "http://" + symbolicName + "-" + ((version == null) ? "null" : version)); - Map tags = new HashMap(); if (version != null) { attr.put(BundleHelper.KEY_VERSION, version); @@ -249,6 +252,11 @@ public abstract class BaseRepositoryAdmi if (processorPID != null) { attr.put(BundleHelper.KEY_RESOURCE_PROCESSOR_PID, processorPID); } + if (size != null) { + attr.put(ArtifactObject.KEY_SIZE, size); + } + + Map tags = new HashMap(); return m_artifactRepository.create(attr, tags); } Modified: ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/StatefulTargetRepositoryTest.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/StatefulTargetRepositoryTest.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/StatefulTargetRepositoryTest.java (original) +++ ace/trunk/org.apache.ace.client.repository.itest/src/org/apache/ace/it/repositoryadmin/StatefulTargetRepositoryTest.java Mon Sep 30 12:00:26 2013 @@ -28,7 +28,6 @@ import static org.apache.ace.client.repo import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -52,8 +51,6 @@ import org.apache.ace.client.repository. import org.apache.ace.log.AuditEvent; import org.apache.ace.log.LogEvent; import org.osgi.framework.InvalidSyntaxException; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventHandler; import org.osgi.service.useradmin.User; /** @@ -65,498 +62,499 @@ public class StatefulTargetRepositoryTes setUpTestCase(); final String targetId = "myNewTarget2"; - + final Map attr = new HashMap(); - attr.put(TargetObject.KEY_ID, targetId); - - final Map tags = new HashMap(); - final StatefulTargetObject sgo = runAndWaitForEvent(new Callable() { - public StatefulTargetObject call() throws Exception { - return m_statefulTargetRepository.preregister(attr, tags); - } - }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); - - assertTrue("Without any deployment versions, and no information in the shop, we should not need to approve.", !sgo.needsApprove()); - assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState()); - assertEquals("We expect the registration state to be New;", StoreState.New, sgo.getStoreState()); - assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion()); - - final ArtifactObject b11 = createBasicBundleObject("bundle1", "1", null); - - FeatureObject g1 = createBasicFeatureObject("feature1"); - FeatureObject g2 = createBasicFeatureObject("feature2"); // note that this feature is not associated to a bundle. - - createDynamicBundle2FeatureAssociation(b11, g1); - - final DistributionObject l1 = createBasicDistributionObject("distribution1"); - - m_feature2distributionRepository.create(g1, l1); - m_feature2distributionRepository.create(g2, l1); - - runAndWaitForEvent(new Callable() { - public Distribution2TargetAssociation call() throws Exception { - return m_distribution2targetRepository.create(l1, sgo.getTargetObject()); - } - }, false, Distribution2TargetAssociation.TOPIC_ADDED, TOPIC_STATUS_CHANGED); - - assertTrue("We added information that influences our target, so we should need to approve it.", sgo.needsApprove()); - assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState()); - assertEquals("We expect the registration state to be Unapproved;", StoreState.Unapproved, sgo.getStoreState()); - assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length); - assertEquals("According to the deployment, this target needs 0 bundles", 0, sgo.getArtifactsFromDeployment().length); - assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion()); - - runAndWaitForEvent(new Callable() { - public Object call() throws Exception { - createBasicDeploymentVersionObject(targetId, "1", b11); - return null; - } - }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); - - assertFalse("We manually created a deployment version that reflects the shop, so no approval should be necessary.", sgo.needsApprove()); - assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState()); - assertEquals("We expect the registration state to be Approved;", StoreState.Approved, sgo.getStoreState()); - assertEquals("According to the shop, this target needs 1 bundle;", 1, sgo.getArtifactsFromShop().length); - assertEquals("According to the deployment, this target needs 1 bundle;", 1, sgo.getArtifactsFromDeployment().length); - - runAndWaitForEvent(new Callable() { - public ArtifactObject call() throws Exception { - return createBasicBundleObject("bundle1", "2", null); - } - }, false, ArtifactObject.TOPIC_ADDED, Artifact2FeatureAssociation.TOPIC_CHANGED, TOPIC_STATUS_CHANGED); - + attr.put(TargetObject.KEY_ID, targetId); + + final Map tags = new HashMap(); + final StatefulTargetObject sgo = runAndWaitForEvent(new Callable() { + public StatefulTargetObject call() throws Exception { + return m_statefulTargetRepository.preregister(attr, tags); + } + }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); + + assertTrue("Without any deployment versions, and no information in the shop, we should not need to approve.", !sgo.needsApprove()); + assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState()); + assertEquals("We expect the registration state to be New;", StoreState.New, sgo.getStoreState()); + assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion()); + + final ArtifactObject b11 = createBasicBundleObject("bundle1", "1", null); + + FeatureObject g1 = createBasicFeatureObject("feature1"); + FeatureObject g2 = createBasicFeatureObject("feature2"); // note that this feature is not associated to a + // bundle. + + createDynamicBundle2FeatureAssociation(b11, g1); + + final DistributionObject l1 = createBasicDistributionObject("distribution1"); + + m_feature2distributionRepository.create(g1, l1); + m_feature2distributionRepository.create(g2, l1); + + runAndWaitForEvent(new Callable() { + public Distribution2TargetAssociation call() throws Exception { + return m_distribution2targetRepository.create(l1, sgo.getTargetObject()); + } + }, false, Distribution2TargetAssociation.TOPIC_ADDED, TOPIC_STATUS_CHANGED); + + assertTrue("We added information that influences our target, so we should need to approve it.", sgo.needsApprove()); + assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState()); + assertEquals("We expect the registration state to be Unapproved;", StoreState.Unapproved, sgo.getStoreState()); + assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length); + assertEquals("According to the deployment, this target needs 0 bundles", 0, sgo.getArtifactsFromDeployment().length); + assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion()); + + runAndWaitForEvent(new Callable() { + public Object call() throws Exception { + createBasicDeploymentVersionObject(targetId, "1", b11); + return null; + } + }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); + + assertFalse("We manually created a deployment version that reflects the shop, so no approval should be necessary.", sgo.needsApprove()); + assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState()); + assertEquals("We expect the registration state to be Approved;", StoreState.Approved, sgo.getStoreState()); + assertEquals("According to the shop, this target needs 1 bundle;", 1, sgo.getArtifactsFromShop().length); + assertEquals("According to the deployment, this target needs 1 bundle;", 1, sgo.getArtifactsFromDeployment().length); + + runAndWaitForEvent(new Callable() { + public ArtifactObject call() throws Exception { + return createBasicBundleObject("bundle1", "2", null); + } + }, false, ArtifactObject.TOPIC_ADDED, Artifact2FeatureAssociation.TOPIC_CHANGED, TOPIC_STATUS_CHANGED); + assertTrue("We added a new version of a bundle that is used by the target, so approval should be necessary.", sgo.needsApprove()); - assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState()); - assertEquals("We expect the registration state to be Unapproved;", StoreState.Unapproved, sgo.getStoreState()); - assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length); - assertEquals("The shop should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromShop()[0].getURL()); - assertEquals("According to the deployment, this target needs 1 bundle", 1, sgo.getArtifactsFromDeployment().length); - assertEquals("The deployment should tell use we need bundle URL 'bundle1-1';", "http://bundle1-1", sgo.getArtifactsFromDeployment()[0].getUrl()); - assertEquals("1", sgo.getCurrentVersion()); - - String newVersion = sgo.approve(); - + assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState()); + assertEquals("We expect the registration state to be Unapproved;", StoreState.Unapproved, sgo.getStoreState()); + assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length); + assertEquals("The shop should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromShop()[0].getURL()); + assertEquals("According to the deployment, this target needs 1 bundle", 1, sgo.getArtifactsFromDeployment().length); + assertEquals("The deployment should tell use we need bundle URL 'bundle1-1';", "http://bundle1-1", sgo.getArtifactsFromDeployment()[0].getUrl()); + assertEquals("1", sgo.getCurrentVersion()); + + String newVersion = sgo.approve(); + runAndWaitForEvent(new Callable() { public Void call() throws Exception { m_repositoryAdmin.commit(); return null; } }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); - - assertFalse("Immediately after approval, no approval is necessary.", sgo.needsApprove()); - assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState()); - assertEquals("We expect the registration state to be Approved;", StoreState.Approved, sgo.getStoreState()); - assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length); - assertEquals("The shop should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromShop()[0].getURL()); - assertEquals("According to the deployment, this target needs 1 bundle", 1, sgo.getArtifactsFromDeployment().length); - assertEquals("The deployment should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromDeployment()[0].getUrl()); - assertEquals( "We expect two deployment versions;", 2, m_deploymentVersionRepository.get().size()); - assertEquals(newVersion, sgo.getCurrentVersion()); - - // clean up this object ourselves; we cannot rely on cleanUp() in this case. - runAndWaitForEvent(new Callable() { - public Object call() throws Exception { - m_statefulTargetRepository.unregister(targetId); - return null; - } - }, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED); - - StatefulTargetObject target = findStatefulTarget(targetId); - assertNull("Target should be removed?!", target); - - cleanUp(); + + assertFalse("Immediately after approval, no approval is necessary.", sgo.needsApprove()); + assertEquals("We expect the registration state to be Registered;", RegistrationState.Registered, sgo.getRegistrationState()); + assertEquals("We expect the registration state to be Approved;", StoreState.Approved, sgo.getStoreState()); + assertEquals("According to the shop, this target needs 1 bundle", 1, sgo.getArtifactsFromShop().length); + assertEquals("The shop should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromShop()[0].getURL()); + assertEquals("According to the deployment, this target needs 1 bundle", 1, sgo.getArtifactsFromDeployment().length); + assertEquals("The deployment should tell use we need bundle URL 'bundle1-2';", "http://bundle1-2", sgo.getArtifactsFromDeployment()[0].getUrl()); + assertEquals("We expect two deployment versions;", 2, m_deploymentVersionRepository.get().size()); + assertEquals(newVersion, sgo.getCurrentVersion()); + + // clean up this object ourselves; we cannot rely on cleanUp() in this case. + runAndWaitForEvent(new Callable() { + public Object call() throws Exception { + m_statefulTargetRepository.unregister(targetId); + return null; + } + }, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED); + + StatefulTargetObject target = findStatefulTarget(targetId); + assertNull("Target should be removed?!", target); + + cleanUp(); } public void testStatefulAuditAndRegister() throws Exception { setUpTestCase(); // preregister target - final Map attr = new HashMap(); - attr.put(TargetObject.KEY_ID, "myNewTarget3"); - final Map tags = new HashMap(); - - final StatefulTargetObject sgo1 = runAndWaitForEvent(new Callable() { - public StatefulTargetObject call() throws Exception { - return m_statefulTargetRepository.preregister(attr, tags); - } - }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); - - // do checks - assertTrue("We just preregistered a target, so it should be registered.", sgo1.isRegistered()); - - // add auditlog data - List events = new ArrayList(); - Properties props = new Properties(); - events.add(new LogEvent("myNewTarget3", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); - // add an (old) set of target properties - Properties props2 = new Properties(); - props2.put("mykey", "myoldvalue"); - props2.put("myoldkey", "myoldvalue"); - events.add(new LogEvent("myNewTarget3", 1, 2, 2, AuditEvent.TARGETPROPERTIES_SET, props2)); - // add a new set of target properties - Properties props3 = new Properties(); - props3.put("mykey", "myvalue"); - events.add(new LogEvent("myNewTarget3", 1, 3, 3, AuditEvent.TARGETPROPERTIES_SET, props3)); - m_auditLogStore.put(events); - m_statefulTargetRepository.refresh(); - - // do checks - TargetObject to = sgo1.getTargetObject(); - assertNotNull("Stateful target should be backed by a target object.", to); - assertEquals("Target should have a property mykey with value myvalue.", "myvalue", to.getTag("target.mykey")); - assertNull("This old key should no longer have been associated with this target.", to.getTag("target.myoldkey")); - assertTrue("Adding auditlog data for a target does not influence its isRegistered().", sgo1.isRegistered()); - - // add auditlog data for other target - events = new ArrayList(); - props = new Properties(); - events.add(new LogEvent("myNewTarget4", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); - m_auditLogStore.put(events); - runAndWaitForEvent(new Callable() { - public Object call() throws Exception { - m_statefulTargetRepository.refresh(); - return false; - } - }, false, TOPIC_ADDED); - final StatefulTargetObject sgo2 = findStatefulTarget("myNewTarget4"); - - // do checks - assertTrue("Adding auditlog data for a target does not influence its isRegistered().", sgo1.isRegistered()); - try { - sgo1.getTargetObject(); - } - catch (IllegalStateException ise) { - assertTrue("We should be able to get sgo1's targetObject.", false); - } - assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered()); - try { - sgo2.getTargetObject(); - assertTrue("We should not be able to get sgo2's targetObject.", false); - } - catch (IllegalStateException ise) { - // expected - } - - // remove original target - runAndWaitForEvent(new Callable() { - public Object call() throws Exception { - m_statefulTargetRepository.unregister(sgo1.getID()); - return null; - } - }, false, TargetObject.TOPIC_REMOVED, TOPIC_STATUS_CHANGED); - - // do checks - assertTrue("sgo1 is now only found in the auditlog, so it cannot be registered.", !sgo1.isRegistered()); - try { - sgo1.getTargetObject(); - assertTrue("We should not be able to get sgo1's targetObject.", false); - } - catch (IllegalStateException ise) { - // expected - } - assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered()); - try { - sgo2.getTargetObject(); - assertTrue("We should not be able to get sgo2's targetObject.", false); - } - catch (IllegalStateException ise) { - // expected - } - - // register second target - runAndWaitForEvent(new Callable() { - public Object call() throws Exception { - sgo2.register(); - return null; - } - }, false, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); - - // do checks - assertTrue("sgo1 is now only found in the auditlog, so it cannot be in registered.", !sgo1.isRegistered()); - try { - sgo1.getTargetObject(); - assertTrue("We should not be able to get sgo1's targetObject.", false); - } - catch (IllegalStateException ise) { - // expected - } - assertTrue("sgo2 has been registered.", sgo2.isRegistered()); - try { - sgo2.getTargetObject(); - } - catch (IllegalStateException ise) { - assertTrue("We should be able to get sgo2's targetObject.", false); - } - - int nrRegistered = - m_statefulTargetRepository.get( - m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")")) - .size(); - assert nrRegistered == 1 : "We expect to filter out one registered target, but we find " + nrRegistered; - - // Finally, create a distribution object - final DistributionObject l1 = createBasicDistributionObject("thedistribution"); - - assertTrue("We just created a Stateful target object, is should not be registered", !sgo1.isRegistered()); - - // register sgo1 again and create an association in 1 go - Distribution2TargetAssociation lgw1 = runAndWaitForEvent(new Callable() { - public Distribution2TargetAssociation call() throws Exception { - sgo1.register(); - return m_distribution2targetRepository.create(l1, sgo1.getTargetObject()); - } - }, false, Distribution2TargetAssociation.TOPIC_ADDED, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); - - // checks - nrRegistered = - m_statefulTargetRepository.get( - m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")")) - .size(); - assert nrRegistered == 2 : "We expect to filter out two registered targets, but we find " + nrRegistered; - assertTrue("A stateful target object should be registered", sgo1.isRegistered()); - assertTrue("The stateful target object should be associated to the distribution.", sgo1.isAssociated(l1, DistributionObject.class)); - assertTrue("Both ends of distribution - stateful target should be satisfied.", lgw1.isSatisfied()); - - cleanUp(); + final Map attr = new HashMap(); + attr.put(TargetObject.KEY_ID, "myNewTarget3"); + final Map tags = new HashMap(); + + final StatefulTargetObject sgo1 = runAndWaitForEvent(new Callable() { + public StatefulTargetObject call() throws Exception { + return m_statefulTargetRepository.preregister(attr, tags); + } + }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); + + // do checks + assertTrue("We just preregistered a target, so it should be registered.", sgo1.isRegistered()); + + // add auditlog data + List events = new ArrayList(); + Properties props = new Properties(); + events.add(new LogEvent("myNewTarget3", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); + // add an (old) set of target properties + Properties props2 = new Properties(); + props2.put("mykey", "myoldvalue"); + props2.put("myoldkey", "myoldvalue"); + events.add(new LogEvent("myNewTarget3", 1, 2, 2, AuditEvent.TARGETPROPERTIES_SET, props2)); + // add a new set of target properties + Properties props3 = new Properties(); + props3.put("mykey", "myvalue"); + events.add(new LogEvent("myNewTarget3", 1, 3, 3, AuditEvent.TARGETPROPERTIES_SET, props3)); + m_auditLogStore.put(events); + m_statefulTargetRepository.refresh(); + + // do checks + TargetObject to = sgo1.getTargetObject(); + assertNotNull("Stateful target should be backed by a target object.", to); + assertEquals("Target should have a property mykey with value myvalue.", "myvalue", to.getTag("target.mykey")); + assertNull("This old key should no longer have been associated with this target.", to.getTag("target.myoldkey")); + assertTrue("Adding auditlog data for a target does not influence its isRegistered().", sgo1.isRegistered()); + + // add auditlog data for other target + events = new ArrayList(); + props = new Properties(); + events.add(new LogEvent("myNewTarget4", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); + m_auditLogStore.put(events); + runAndWaitForEvent(new Callable() { + public Object call() throws Exception { + m_statefulTargetRepository.refresh(); + return false; + } + }, false, TOPIC_ADDED); + final StatefulTargetObject sgo2 = findStatefulTarget("myNewTarget4"); + + // do checks + assertTrue("Adding auditlog data for a target does not influence its isRegistered().", sgo1.isRegistered()); + try { + sgo1.getTargetObject(); + } + catch (IllegalStateException ise) { + assertTrue("We should be able to get sgo1's targetObject.", false); + } + assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered()); + try { + sgo2.getTargetObject(); + assertTrue("We should not be able to get sgo2's targetObject.", false); + } + catch (IllegalStateException ise) { + // expected + } + + // remove original target + runAndWaitForEvent(new Callable() { + public Object call() throws Exception { + m_statefulTargetRepository.unregister(sgo1.getID()); + return null; + } + }, false, TargetObject.TOPIC_REMOVED, TOPIC_STATUS_CHANGED); + + // do checks + assertTrue("sgo1 is now only found in the auditlog, so it cannot be registered.", !sgo1.isRegistered()); + try { + sgo1.getTargetObject(); + assertTrue("We should not be able to get sgo1's targetObject.", false); + } + catch (IllegalStateException ise) { + // expected + } + assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered()); + try { + sgo2.getTargetObject(); + assertTrue("We should not be able to get sgo2's targetObject.", false); + } + catch (IllegalStateException ise) { + // expected + } + + // register second target + runAndWaitForEvent(new Callable() { + public Object call() throws Exception { + sgo2.register(); + return null; + } + }, false, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); + + // do checks + assertTrue("sgo1 is now only found in the auditlog, so it cannot be in registered.", !sgo1.isRegistered()); + try { + sgo1.getTargetObject(); + assertTrue("We should not be able to get sgo1's targetObject.", false); + } + catch (IllegalStateException ise) { + // expected + } + assertTrue("sgo2 has been registered.", sgo2.isRegistered()); + try { + sgo2.getTargetObject(); + } + catch (IllegalStateException ise) { + assertTrue("We should be able to get sgo2's targetObject.", false); + } + + int nrRegistered = + m_statefulTargetRepository.get( + m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")")) + .size(); + assert nrRegistered == 1 : "We expect to filter out one registered target, but we find " + nrRegistered; + + // Finally, create a distribution object + final DistributionObject l1 = createBasicDistributionObject("thedistribution"); + + assertTrue("We just created a Stateful target object, is should not be registered", !sgo1.isRegistered()); + + // register sgo1 again and create an association in 1 go + Distribution2TargetAssociation lgw1 = runAndWaitForEvent(new Callable() { + public Distribution2TargetAssociation call() throws Exception { + sgo1.register(); + return m_distribution2targetRepository.create(l1, sgo1.getTargetObject()); + } + }, false, Distribution2TargetAssociation.TOPIC_ADDED, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); + + // checks + nrRegistered = + m_statefulTargetRepository.get( + m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")")) + .size(); + assert nrRegistered == 2 : "We expect to filter out two registered targets, but we find " + nrRegistered; + assertTrue("A stateful target object should be registered", sgo1.isRegistered()); + assertTrue("The stateful target object should be associated to the distribution.", sgo1.isAssociated(l1, DistributionObject.class)); + assertTrue("Both ends of distribution - stateful target should be satisfied.", lgw1.isSatisfied()); + + cleanUp(); } public void testStatefulAuditAndRemove() throws Exception { setUpTestCase(); // preregister gateway - final Map attr = new HashMap(); - attr.put(TargetObject.KEY_ID, "myNewGatewayA"); - final Map tags = new HashMap(); - - final StatefulTargetObject sgo1 = runAndWaitForEvent(new Callable() { - public StatefulTargetObject call() throws Exception { - return m_statefulTargetRepository.preregister(attr, tags); - } - }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); - - // do checks - assertTrue("We just preregistered a gateway, so it should be registered.", sgo1.isRegistered()); - - // add auditlog data - List events = new ArrayList(); - Properties props = new Properties(); - events.add(new LogEvent("myNewGatewayA", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); - m_auditLogStore.put(events); - m_statefulTargetRepository.refresh(); - - // do checks - assertTrue("Adding auditlog data for a gateway does not influence its isRegistered().", sgo1.isRegistered()); - try { - sgo1.getTargetObject(); - } - catch (IllegalStateException ise) { - assertTrue("We should be able to get sgo1's gatewayObject.", false); - } - // add auditlog data for other gateway - events = new ArrayList(); - props = new Properties(); - events.add(new LogEvent("myNewGatewayB", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); - m_auditLogStore.put(events); - runAndWaitForEvent(new Callable() { - public Object call() throws Exception { - m_statefulTargetRepository.refresh(); - return false; - } - }, false, TOPIC_ADDED); - final StatefulTargetObject sgo2 = findStatefulTarget("myNewGatewayB"); - - // do checks - assertTrue("Adding auditlog data for a gateway does not influence its isRegistered().", sgo1.isRegistered()); - try { - sgo1.getTargetObject(); - } - catch (IllegalStateException ise) { - assertTrue("We should be able to get sgo1's gatewayObject.", false); - } - assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered()); - try { - sgo2.getTargetObject(); - assertTrue("We should not be able to get sgo2's gatewayObject.", false); - } - catch (IllegalStateException ise) { - // expected - } - // remove original gateway - runAndWaitForEvent(new Callable() { - public Object call() throws Exception { - m_statefulTargetRepository.remove(sgo1); - return null; - } - }, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED); - - // do checks - assertTrue("sgo1 is now only found in the auditlog, so it cannot be registered.", !sgo1.isRegistered()); - try { - sgo1.getTargetObject(); - assertTrue("We should not be able to get sgo1's gatewayObject.", false); - } - catch (IllegalStateException ise) { - // expected - } - - assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered()); - try { - sgo2.getTargetObject(); - assertTrue("We should not be able to get sgo2's gatewayObject.", false); - } - catch (IllegalStateException ise) { - // expected - } - - // register second gateway - runAndWaitForEvent(new Callable() { - public Object call() throws Exception { - sgo2.register(); - return null; - } - }, false, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); - - // do checks - assertTrue("sgo1 is now only found in the auditlog, so it cannot be in registered.", !sgo1.isRegistered()); - try { - sgo1.getTargetObject(); - assertTrue("We should not be able to get sgo1's gatewayObject.", false); - } - catch (IllegalStateException ise) { - // expected - } - assertTrue("sgo2 has been registered.", sgo2.isRegistered()); - try { - sgo2.getTargetObject(); - } - catch (IllegalStateException ise) { - assertTrue("We should be able to get sgo2's gatewayObject.", false); - } - - int nrRegistered = m_statefulTargetRepository.get(m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")")).size(); - assert nrRegistered == 1 : "We expect to filter out one registered gateway, but we find " + nrRegistered; - - // Finally, refresh the repository; it should cause sgo1 to be re-created (due to its audit log)... - // ACE-167 does not cover this scenario, but at a later time this should be fixed as well (see ACE-230). - m_statefulTargetRepository.refresh(); - - int count = m_statefulTargetRepository.get(m_bundleContext.createFilter("(" + KEY_ID + "=myNewGatewayA)")).size(); - assertTrue("We expected sgo1 to be re-created!", count == 1); - - cleanUp(); + final Map attr = new HashMap(); + attr.put(TargetObject.KEY_ID, "myNewGatewayA"); + final Map tags = new HashMap(); + + final StatefulTargetObject sgo1 = runAndWaitForEvent(new Callable() { + public StatefulTargetObject call() throws Exception { + return m_statefulTargetRepository.preregister(attr, tags); + } + }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); + + // do checks + assertTrue("We just preregistered a gateway, so it should be registered.", sgo1.isRegistered()); + + // add auditlog data + List events = new ArrayList(); + Properties props = new Properties(); + events.add(new LogEvent("myNewGatewayA", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); + m_auditLogStore.put(events); + m_statefulTargetRepository.refresh(); + + // do checks + assertTrue("Adding auditlog data for a gateway does not influence its isRegistered().", sgo1.isRegistered()); + try { + sgo1.getTargetObject(); + } + catch (IllegalStateException ise) { + assertTrue("We should be able to get sgo1's gatewayObject.", false); + } + // add auditlog data for other gateway + events = new ArrayList(); + props = new Properties(); + events.add(new LogEvent("myNewGatewayB", 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); + m_auditLogStore.put(events); + runAndWaitForEvent(new Callable() { + public Object call() throws Exception { + m_statefulTargetRepository.refresh(); + return false; + } + }, false, TOPIC_ADDED); + final StatefulTargetObject sgo2 = findStatefulTarget("myNewGatewayB"); + + // do checks + assertTrue("Adding auditlog data for a gateway does not influence its isRegistered().", sgo1.isRegistered()); + try { + sgo1.getTargetObject(); + } + catch (IllegalStateException ise) { + assertTrue("We should be able to get sgo1's gatewayObject.", false); + } + assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered()); + try { + sgo2.getTargetObject(); + assertTrue("We should not be able to get sgo2's gatewayObject.", false); + } + catch (IllegalStateException ise) { + // expected + } + // remove original gateway + runAndWaitForEvent(new Callable() { + public Object call() throws Exception { + m_statefulTargetRepository.remove(sgo1); + return null; + } + }, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED); + + // do checks + assertTrue("sgo1 is now only found in the auditlog, so it cannot be registered.", !sgo1.isRegistered()); + try { + sgo1.getTargetObject(); + assertTrue("We should not be able to get sgo1's gatewayObject.", false); + } + catch (IllegalStateException ise) { + // expected + } + + assertTrue("sgo2 is only found in the auditlog, so it cannot be in registered.", !sgo2.isRegistered()); + try { + sgo2.getTargetObject(); + assertTrue("We should not be able to get sgo2's gatewayObject.", false); + } + catch (IllegalStateException ise) { + // expected + } + + // register second gateway + runAndWaitForEvent(new Callable() { + public Object call() throws Exception { + sgo2.register(); + return null; + } + }, false, TargetObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); + + // do checks + assertTrue("sgo1 is now only found in the auditlog, so it cannot be in registered.", !sgo1.isRegistered()); + try { + sgo1.getTargetObject(); + assertTrue("We should not be able to get sgo1's gatewayObject.", false); + } + catch (IllegalStateException ise) { + // expected + } + assertTrue("sgo2 has been registered.", sgo2.isRegistered()); + try { + sgo2.getTargetObject(); + } + catch (IllegalStateException ise) { + assertTrue("We should be able to get sgo2's gatewayObject.", false); + } + + int nrRegistered = m_statefulTargetRepository.get(m_bundleContext.createFilter("(" + KEY_REGISTRATION_STATE + "=" + RegistrationState.Registered + ")")).size(); + assert nrRegistered == 1 : "We expect to filter out one registered gateway, but we find " + nrRegistered; + + // Finally, refresh the repository; it should cause sgo1 to be re-created (due to its audit log)... + // ACE-167 does not cover this scenario, but at a later time this should be fixed as well (see ACE-230). + m_statefulTargetRepository.refresh(); + + int count = m_statefulTargetRepository.get(m_bundleContext.createFilter("(" + KEY_ID + "=myNewGatewayA)")).size(); + assertTrue("We expected sgo1 to be re-created!", count == 1); + + cleanUp(); } public void testStatefulAuditLog() throws Exception { setUpTestCase(); - + final String targetId = String.format("target-%s", Long.toHexString(System.nanoTime())); List events = new ArrayList(); - Properties props = new Properties(); + Properties props = new Properties(); + + events.add(new LogEvent(targetId, 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); + // fill auditlog; no install data + m_auditLogStore.put(events); + + runAndWaitForEvent(new Callable() { + public Void call() throws Exception { + m_statefulTargetRepository.refresh(); + return null; + } + }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_ADDED); - events.add(new LogEvent(targetId, 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); - // fill auditlog; no install data - m_auditLogStore.put(events); - - runAndWaitForEvent(new Callable() { - public Void call() throws Exception { - m_statefulTargetRepository.refresh(); - return null; - } - }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_ADDED); - - StatefulTargetObject sgo = findStatefulTarget(targetId); - assertNotNull("Expected new target object to become available!", sgo); - - assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState()); - - // fill auditlog with complete-data - events = new ArrayList(); - props = new Properties(); - props.put(AuditEvent.KEY_NAME, "mypackage"); - props.put(AuditEvent.KEY_VERSION, "123"); - events.add(new LogEvent(targetId, 1, 2, 2, AuditEvent.DEPLOYMENTCONTROL_INSTALL, props)); - - m_auditLogStore.put(events); - - runAndWaitForEvent(new Callable() { - public Void call() throws Exception { - m_statefulTargetRepository.refresh(); - return null; - } - }, false, StatefulTargetObject.TOPIC_STATUS_CHANGED, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED); - - assertEquals("Our last install version should be 123;", "123", sgo.getLastInstallVersion()); - assertEquals("We expect our object's provisioning state to be InProgress;", ProvisioningState.InProgress, sgo.getProvisioningState()); - - // fill auditlog with install data - events = new ArrayList(); - props = new Properties(); - props.put(AuditEvent.KEY_NAME, "mypackage"); - props.put(AuditEvent.KEY_VERSION, "123"); - props.put(AuditEvent.KEY_SUCCESS, "false"); - events.add(new LogEvent(targetId, 1, 3, 3, AuditEvent.DEPLOYMENTADMIN_COMPLETE, props)); - - m_auditLogStore.put(events); - - runAndWaitForEvent(new Callable() { - public Void call() throws Exception { - m_statefulTargetRepository.refresh(); - return null; - } - }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED); - - assertEquals("Our last install version should be 123;", "123", sgo.getLastInstallVersion()); - assertEquals("We expect our object's provisioning state to be Failed;", ProvisioningState.Failed, sgo.getProvisioningState()); - assertFalse("Our last install was not successful, but according to the sgo it was.", sgo.getLastInstallSuccess()); - - sgo.acknowledgeInstallVersion("123"); - - assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState()); - - // add another install event. - events = new ArrayList(); - props = new Properties(); - props.put(AuditEvent.KEY_NAME, "mypackage"); - props.put(AuditEvent.KEY_VERSION, "124"); - events.add(new LogEvent(targetId, 1, 4, 4, AuditEvent.DEPLOYMENTCONTROL_INSTALL, props)); - - m_auditLogStore.put(events); - - runAndWaitForEvent(new Callable() { - public Void call() throws Exception { - m_statefulTargetRepository.refresh(); - return null; - } - }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED); - - assertEquals("Our last install version should be 124;", "124", sgo.getLastInstallVersion()); - assertEquals("We expect our object's provisioning state to be InProgress;", ProvisioningState.InProgress, sgo.getProvisioningState()); - - // fill auditlog with install data - events = new ArrayList(); - props = new Properties(); - props.put(AuditEvent.KEY_NAME, "mypackage"); - props.put(AuditEvent.KEY_VERSION, "124"); - props.put(AuditEvent.KEY_SUCCESS, "true"); - events.add(new LogEvent(targetId, 1, 5, 5, AuditEvent.DEPLOYMENTADMIN_COMPLETE, props)); - - m_auditLogStore.put(events); - - runAndWaitForEvent(new Callable() { - public Void call() throws Exception { - m_statefulTargetRepository.refresh(); - return null; - } - }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED); - - assertEquals("Our last install version should be 124;", "124", sgo.getLastInstallVersion()); - assertEquals("We expect our object's provisioning state to be OK;", ProvisioningState.OK, sgo.getProvisioningState()); - assertTrue("Our last install was successful, but according to the sgo it was not.", sgo.getLastInstallSuccess()); - - sgo.acknowledgeInstallVersion("124"); - - assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState()); + StatefulTargetObject sgo = findStatefulTarget(targetId); + assertNotNull("Expected new target object to become available!", sgo); + + assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState()); + + // fill auditlog with complete-data + events = new ArrayList(); + props = new Properties(); + props.put(AuditEvent.KEY_NAME, "mypackage"); + props.put(AuditEvent.KEY_VERSION, "123"); + events.add(new LogEvent(targetId, 1, 2, 2, AuditEvent.DEPLOYMENTCONTROL_INSTALL, props)); + + m_auditLogStore.put(events); + + runAndWaitForEvent(new Callable() { + public Void call() throws Exception { + m_statefulTargetRepository.refresh(); + return null; + } + }, false, StatefulTargetObject.TOPIC_STATUS_CHANGED, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED); + + assertEquals("Our last install version should be 123;", "123", sgo.getLastInstallVersion()); + assertEquals("We expect our object's provisioning state to be InProgress;", ProvisioningState.InProgress, sgo.getProvisioningState()); + + // fill auditlog with install data + events = new ArrayList(); + props = new Properties(); + props.put(AuditEvent.KEY_NAME, "mypackage"); + props.put(AuditEvent.KEY_VERSION, "123"); + props.put(AuditEvent.KEY_SUCCESS, "false"); + events.add(new LogEvent(targetId, 1, 3, 3, AuditEvent.DEPLOYMENTADMIN_COMPLETE, props)); + + m_auditLogStore.put(events); + + runAndWaitForEvent(new Callable() { + public Void call() throws Exception { + m_statefulTargetRepository.refresh(); + return null; + } + }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED); + + assertEquals("Our last install version should be 123;", "123", sgo.getLastInstallVersion()); + assertEquals("We expect our object's provisioning state to be Failed;", ProvisioningState.Failed, sgo.getProvisioningState()); + assertFalse("Our last install was not successful, but according to the sgo it was.", sgo.getLastInstallSuccess()); + + sgo.acknowledgeInstallVersion("123"); + + assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState()); + + // add another install event. + events = new ArrayList(); + props = new Properties(); + props.put(AuditEvent.KEY_NAME, "mypackage"); + props.put(AuditEvent.KEY_VERSION, "124"); + events.add(new LogEvent(targetId, 1, 4, 4, AuditEvent.DEPLOYMENTCONTROL_INSTALL, props)); + + m_auditLogStore.put(events); + + runAndWaitForEvent(new Callable() { + public Void call() throws Exception { + m_statefulTargetRepository.refresh(); + return null; + } + }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED); + + assertEquals("Our last install version should be 124;", "124", sgo.getLastInstallVersion()); + assertEquals("We expect our object's provisioning state to be InProgress;", ProvisioningState.InProgress, sgo.getProvisioningState()); + + // fill auditlog with install data + events = new ArrayList(); + props = new Properties(); + props.put(AuditEvent.KEY_NAME, "mypackage"); + props.put(AuditEvent.KEY_VERSION, "124"); + props.put(AuditEvent.KEY_SUCCESS, "true"); + events.add(new LogEvent(targetId, 1, 5, 5, AuditEvent.DEPLOYMENTADMIN_COMPLETE, props)); + + m_auditLogStore.put(events); + + runAndWaitForEvent(new Callable() { + public Void call() throws Exception { + m_statefulTargetRepository.refresh(); + return null; + } + }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_STATUS_CHANGED); + + assertEquals("Our last install version should be 124;", "124", sgo.getLastInstallVersion()); + assertEquals("We expect our object's provisioning state to be OK;", ProvisioningState.OK, sgo.getProvisioningState()); + assertTrue("Our last install was successful, but according to the sgo it was not.", sgo.getLastInstallSuccess()); + + sgo.acknowledgeInstallVersion("124"); + + assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState()); } public void testStatefulCreateRemove() throws Exception { @@ -565,95 +563,163 @@ public class StatefulTargetRepositoryTes final String targetId = "myNewTarget1"; final Map attr = new HashMap(); - attr.put(TargetObject.KEY_ID, targetId); - final Map tags = new HashMap(); - - try { - m_statefulTargetRepository.create(attr, tags); - fail("Creating a stateful target repository should not be allowed."); - } - catch (UnsupportedOperationException uoe) { - // expected - } - - final StatefulTargetObject sgo = runAndWaitForEvent(new Callable() { - public StatefulTargetObject call() throws Exception { - return m_statefulTargetRepository.preregister(attr, tags); - } - }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); - - assertNotNull("We expect to found our new target in the repository!", findStatefulTarget(targetId)); - - // Removing stateful objects is now (partially) supported; see ACE-167 & ACE-230... - m_statefulTargetRepository.remove(sgo); - - assertNull("We expect to NOT found our target in the repository!", findStatefulTarget(targetId)); - - cleanUp(); + attr.put(TargetObject.KEY_ID, targetId); + final Map tags = new HashMap(); + + try { + m_statefulTargetRepository.create(attr, tags); + fail("Creating a stateful target repository should not be allowed."); + } + catch (UnsupportedOperationException uoe) { + // expected + } + + final StatefulTargetObject sgo = runAndWaitForEvent(new Callable() { + public StatefulTargetObject call() throws Exception { + return m_statefulTargetRepository.preregister(attr, tags); + } + }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); + + assertNotNull("We expect to found our new target in the repository!", findStatefulTarget(targetId)); + + // Removing stateful objects is now (partially) supported; see ACE-167 & ACE-230... + m_statefulTargetRepository.remove(sgo); + + assertNull("We expect to NOT found our target in the repository!", findStatefulTarget(targetId)); + + cleanUp(); } public void testStatefulSetAutoApprove() throws Exception { setUpTestCase(); final String targetId = "a_target"; - + // register target with - final Map attr = new HashMap(); - attr.put(TargetObject.KEY_ID, targetId); - attr.put(TargetObject.KEY_AUTO_APPROVE, String.valueOf(true)); - final Map tags = new HashMap(); - - final StatefulTargetObject sgo = runAndWaitForEvent(new Callable() { - public StatefulTargetObject call() throws Exception { - return m_statefulTargetRepository.preregister(attr, tags); - } - }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); - - assertNotNull("We expect to found our new target in the repository!", findStatefulTarget(targetId)); - - assertTrue("The target should have auto approved value: true but got: false.", sgo.getAutoApprove()); - - sgo.setAutoApprove(false); - - assertFalse("The target should have auto approved value: false but got: true.", sgo.getAutoApprove()); - - // clean up - runAndWaitForEvent(new Callable() { - public Object call() throws Exception { - m_statefulTargetRepository.unregister(targetId); - return null; - } - }, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED); + final Map attr = new HashMap(); + attr.put(TargetObject.KEY_ID, targetId); + attr.put(TargetObject.KEY_AUTO_APPROVE, String.valueOf(true)); + final Map tags = new HashMap(); + + final StatefulTargetObject sgo = runAndWaitForEvent(new Callable() { + public StatefulTargetObject call() throws Exception { + return m_statefulTargetRepository.preregister(attr, tags); + } + }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); + + assertNotNull("We expect to found our new target in the repository!", findStatefulTarget(targetId)); + + assertTrue("The target should have auto approved value: true but got: false.", sgo.getAutoApprove()); + + sgo.setAutoApprove(false); + + assertFalse("The target should have auto approved value: false but got: true.", sgo.getAutoApprove()); + + // clean up + runAndWaitForEvent(new Callable() { + public Object call() throws Exception { + m_statefulTargetRepository.unregister(targetId); + return null; + } + }, false, TargetObject.TOPIC_REMOVED, TOPIC_REMOVED); } - public void testStrangeNamesInTargets() throws Exception { + public void testStrangeNamesInTargets() throws Exception { setUpTestCase(); - + final String targetID = ":)"; List events = new ArrayList(); - Properties props = new Properties(); + Properties props = new Properties(); + + // add a target with a weird name. + events.add(new LogEvent(targetID, 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); + // fill auditlog; no install data + m_auditLogStore.put(events); + + runAndWaitForEvent(new Callable() { + public Void call() throws Exception { + m_statefulTargetRepository.refresh(); + return null; + } + }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_ADDED); + + StatefulTargetObject sgo = findStatefulTarget(targetID); + assertNotNull("Target not added to repository?!", sgo); + + sgo.register(); + + assertTrue("After registring our target, we assume it to be registered.", sgo.getRegistrationState().equals(RegistrationState.Registered)); + + assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState()); + } + + /** + * Tests that the artifact sizes are propagated to the {@link DeploymentArtifact}s in the deployment repository, see + * ACE-384. + */ + public void testDeploymentVersionObjectSize() throws Exception { + setUpTestCase(); + + final String targetId = "myNewTarget3"; - // add a target with a weird name. - events.add(new LogEvent(targetID, 1, 1, 1, AuditEvent.FRAMEWORK_STARTED, props)); - // fill auditlog; no install data - m_auditLogStore.put(events); - - runAndWaitForEvent(new Callable() { - public Void call() throws Exception { - m_statefulTargetRepository.refresh(); - return null; - } - }, false, StatefulTargetObject.TOPIC_AUDITEVENTS_CHANGED, StatefulTargetObject.TOPIC_ADDED); - - StatefulTargetObject sgo = findStatefulTarget(targetID); - assertNotNull("Target not added to repository?!", sgo); - - sgo.register(); - - assertTrue("After registring our target, we assume it to be registered.", sgo.getRegistrationState().equals(RegistrationState.Registered)); + final Map attr = new HashMap(); + attr.put(TargetObject.KEY_ID, targetId); + + final Map tags = new HashMap(); + final StatefulTargetObject sgo = runAndWaitForEvent(new Callable() { + public StatefulTargetObject call() throws Exception { + return m_statefulTargetRepository.preregister(attr, tags); + } + }, false, TargetObject.TOPIC_ADDED, TOPIC_ADDED); + + assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion()); + + final ArtifactObject b1 = createBasicBundleObject("bundle1", "1", null, "10"); + final ArtifactObject b2 = createBasicBundleObject("bundle2", "1", null); + final ArtifactObject b3 = createBasicBundleObject("bundle3", "1", null, "foo"); + + FeatureObject f1 = createBasicFeatureObject("feature1"); + + createDynamicBundle2FeatureAssociation(b1, f1); + createDynamicBundle2FeatureAssociation(b2, f1); + createDynamicBundle2FeatureAssociation(b3, f1); + + final DistributionObject d1 = createBasicDistributionObject("distribution1"); + + m_feature2distributionRepository.create(f1, d1); + + runAndWaitForEvent(new Callable() { + public Distribution2TargetAssociation call() throws Exception { + return m_distribution2targetRepository.create(d1, sgo.getTargetObject()); + } + }, false, Distribution2TargetAssociation.TOPIC_ADDED, TOPIC_STATUS_CHANGED); + + assertEquals(UNKNOWN_VERSION, sgo.getCurrentVersion()); - assertEquals("We expect our object's provisioning state to be Idle;", ProvisioningState.Idle, sgo.getProvisioningState()); + DeploymentVersionObject deploymentVersionObject = runAndWaitForEvent(new Callable() { + public DeploymentVersionObject call() throws Exception { + return createBasicDeploymentVersionObject(targetId, "1", b1, b2, b3); + } + }, false, DeploymentVersionObject.TOPIC_ADDED, TOPIC_STATUS_CHANGED); + + assertNotNull(deploymentVersionObject); + + DeploymentArtifact[] deploymentArtifacts = deploymentVersionObject.getDeploymentArtifacts(); + for (DeploymentArtifact deploymentArtifact : deploymentArtifacts) { + if (deploymentArtifact.getUrl().contains("bundle1")) { + assertEquals(10L, deploymentArtifact.getSize()); + } + else if (deploymentArtifact.getUrl().contains("bundle2")) { + assertEquals(-1L, deploymentArtifact.getSize()); + } + else if (deploymentArtifact.getUrl().contains("bundle3")) { + assertEquals(-1L, deploymentArtifact.getSize()); + } + else { + fail("Unknown bundle?! " + deploymentArtifact.getUrl()); + } + } } private DeploymentVersionObject createBasicDeploymentVersionObject(String targetID, String version, @@ -671,11 +737,11 @@ public class StatefulTargetRepositoryTes if (artifact.getAttribute(BundleHelper.KEY_VERSION) != null) { directives.put(BundleHelper.KEY_VERSION, artifact.getAttribute(BundleHelper.KEY_VERSION)); } - artifacts.add(m_deploymentVersionRepository.createDeploymentArtifact(artifact.getURL(), directives)); + artifacts.add(m_deploymentVersionRepository.createDeploymentArtifact(artifact.getURL(), artifact.getSize(), directives)); } return m_deploymentVersionRepository.create(attr, tags, artifacts.toArray(new DeploymentArtifact[0])); } - + private Artifact2FeatureAssociation createDynamicBundle2FeatureAssociation(ArtifactObject artifact, FeatureObject feature) { Map properties = new HashMap(); @@ -684,8 +750,7 @@ public class StatefulTargetRepositoryTes } /** - * The following code is borrowed from RepositoryTest.java, and is used to instantiate and - * use repository servlets. + * The following code is borrowed from RepositoryTest.java, and is used to instantiate and use repository servlets. */ private StatefulTargetObject findStatefulTarget(String targetID) throws InvalidSyntaxException { for (StatefulTargetObject sgo : m_statefulTargetRepository.get()) { @@ -697,13 +762,13 @@ public class StatefulTargetRepositoryTes } /** - * @throws IOException - * @throws InterruptedException - * @throws InvalidSyntaxException - */ - private void setUpTestCase() throws Exception { - User user = new MockUser(); - String customer = "customer-" + Long.toHexString(System.currentTimeMillis()); + * @throws IOException + * @throws InterruptedException + * @throws InvalidSyntaxException + */ + private void setUpTestCase() throws Exception { + User user = new MockUser(); + String customer = "customer-" + Long.toHexString(System.currentTimeMillis()); startRepositoryService(); @@ -722,5 +787,5 @@ public class StatefulTargetRepositoryTes m_repositoryAdmin.login(loginContext); m_repositoryAdmin.checkout(); - } + } } Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ArtifactResource.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ArtifactResource.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ArtifactResource.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/ArtifactResource.java Mon Sep 30 12:00:26 2013 @@ -26,8 +26,8 @@ import java.net.URL; /** * Denotes a 'physical' artifact that is located by an URL, and provide means to access the contents of this artifact. *

- * Note that an artifact can be located on a remote machine, which might need credentials to access its contents. - * This interface allows one to access the resource without having to worry about supplying those credentials, as the + * Note that an artifact can be located on a remote machine, which might need credentials to access its contents. This + * interface allows one to access the resource without having to worry about supplying those credentials, as the * implementor of this class has to worry about this instead. *

*/ @@ -36,9 +36,9 @@ public interface ArtifactResource { /** * Returns the location of this artifact. *

- * Note that although {@link URL#openConnection()} allows you to directly open a connection to the resource, - * in fact this may fail due to, for example, missing authentication credentials. Use {@link #openStream()} - * instead to access the contents of the resource. + * Note that although {@link URL#openConnection()} allows you to directly open a connection to the resource, in fact + * this may fail due to, for example, missing authentication credentials. Use {@link #openStream()} instead to + * access the contents of the resource. *

* * @return the URL to the 'physical' location of the artifact, never null. @@ -46,10 +46,20 @@ public interface ArtifactResource { URL getURL(); /** + * Returns the size, in bytes, of this artifact. + * + * @return a size, in bytes, >= 0L. If the size of this artifact is unknown, -1L should be returned. + * @throws IOException + * in case of I/O errors determining the size of the artifact. + */ + long getSize() throws IOException; + + /** * Provides access to the contents of the artifact. * - * @return an input stream, never null. - * @throws IOException in case of I/O errors opening the artifact. + * @return an input stream, never null. + * @throws IOException + * in case of I/O errors opening the artifact. * @see #getURL() */ InputStream openStream() throws IOException; Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactObjectImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactObjectImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactObjectImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactObjectImpl.java Mon Sep 30 12:00:26 2013 @@ -30,8 +30,8 @@ import org.apache.ace.client.repository. import com.thoughtworks.xstream.io.HierarchicalStreamReader; /** - * Implementation class for the ArtifactObject. For 'what it does', see ArtifactObject, - * for 'how it works', see RepositoryObjectImpl.
+ * Implementation class for the ArtifactObject. For 'what it does', see ArtifactObject, for 'how it works', see + * RepositoryObjectImpl.
*
* Some functionality of this class is delegated to implementers of {@link ArtifactHelper}. */ @@ -39,8 +39,8 @@ public class ArtifactObjectImpl extends private final static String XML_NODE = "artifact"; /* - * As a general rule, RepositoryObjects do not know about their repository. However, since the Helper - * to be used is dictated by the repository, this rule is broken for this class. + * As a general rule, RepositoryObjects do not know about their repository. However, since the Helper to be used is + * dictated by the repository, this rule is broken for this class. */ private final ArtifactRepositoryImpl m_repo; @@ -58,7 +58,7 @@ public class ArtifactObjectImpl extends super(reader, notifier, XML_NODE); m_repo = repo; } - + private static String[] completeMandatoryAttributes(String[] mandatory) { String[] result = new String[mandatory.length + 1]; for (int i = 0; i < mandatory.length; i++) { @@ -91,6 +91,19 @@ public class ArtifactObjectImpl extends return getHelper().getComparator(); } + @Override + public long getSize() { + String size = getAttribute(KEY_SIZE); + try { + if (size != null) { + return Long.parseLong(size); + } + } + catch (NumberFormatException exception) { + } + return -1L; + } + public String getURL() { return getAttribute(KEY_URL); } @@ -127,7 +140,7 @@ public class ArtifactObjectImpl extends String[] getDefiningKeys() { return getHelper().getDefiningKeys().clone(); } - + private ArtifactHelper getHelper() { // getMimetype is safe, as is getHelper, and m_repo is final, so no // need to synchronize here... Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java Mon Sep 30 12:00:26 2013 @@ -22,7 +22,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; @@ -340,6 +339,7 @@ public class ArtifactRepositoryImpl exte helper.checkAttributes(attributes); attributes.put(ArtifactObject.KEY_ARTIFACT_DESCRIPTION, ""); + attributes.put(ArtifactObject.KEY_SIZE, Long.toString(resource.getSize())); if (overwrite) { attributes.put(ArtifactObject.KEY_MIMETYPE, mimetype); } @@ -574,6 +574,15 @@ public class ArtifactRepositoryImpl exte return url; } + @Override + public long getSize() throws IOException { + // Take care of the fact that an URL could need credentials to be accessible!!! + URLConnection conn = m_connectionFactory.createConnection(getURL()); + conn.setUseCaches(true); + return conn.getContentLength(); + } + + @Override public InputStream openStream() throws IOException { // Take care of the fact that an URL could need credentials to be accessible!!! URLConnection conn = m_connectionFactory.createConnection(getURL()); Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentArtifactImpl.java Mon Sep 30 12:00:26 2013 @@ -26,46 +26,58 @@ import org.apache.ace.client.repository. import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; - /** - * This class is a basic implementation of DeploymentArtifact, with additional facilities - * for serializing this artifacts with its directives. + * This class is a basic implementation of DeploymentArtifact, with additional facilities for serializing this artifacts + * with its directives. */ public class DeploymentArtifactImpl implements DeploymentArtifact { private final static String XML_NODE = "deploymentArtifact"; private final static String XML_NODE_URL = "url"; + private final static String XML_NODE_SIZE = "size"; private final static String XML_NODE_DIRECTIVES = "directives"; + private final String m_url; + private final long m_size; private final Map m_directives = new HashMap(); /** * Creates a new DeploymentArtifactImpl. - * @param url The url to the new artifact, as a string; should not be null; + * + * @param url + * The url to the new artifact, as a string; should not be null; + * @param size + * the estimated size of the new artifact, in bytes, or -1L if unknown. */ - public DeploymentArtifactImpl(String url) { + public DeploymentArtifactImpl(String url, long size) { if (url == null) { throw new IllegalArgumentException("The url should not be null."); } m_url = url; + m_size = size; } /** * Creates a new DeploymentArtifactImpl by deserializing it from an XML stream. - * @param reader A stream reader for the XML representation of this object. + * + * @param reader + * A stream reader for the XML representation of this object. */ public DeploymentArtifactImpl(HierarchicalStreamReader reader) { - reader.moveDown(); + reader.moveDown(); // url m_url = reader.getValue(); - reader.moveUp(); + reader.moveUp(); // deploymentArtifact + reader.moveDown(); // size + String size = reader.getValue(); + m_size = (size == null) ? -1L : Long.parseLong(size); + reader.moveUp(); // deploymentArtifact - reader.moveDown(); + reader.moveDown(); // directives while (reader.hasMoreChildren()) { - reader.moveDown(); + reader.moveDown(); // directive m_directives.put(reader.getNodeName(), reader.getValue()); reader.moveUp(); } reader.moveUp(); - } /** @@ -75,9 +87,13 @@ public class DeploymentArtifactImpl impl writer.startNode(XML_NODE); writer.startNode(XML_NODE_URL); - writer.setValue(m_url); + writer.setValue(getUrl()); writer.endNode(); // url node + writer.startNode(XML_NODE_SIZE); + writer.setValue(Long.toString(getSize())); + writer.endNode(); // size node + writer.startNode(XML_NODE_DIRECTIVES); for (Map.Entry entry : m_directives.entrySet()) { writer.startNode(entry.getKey()); @@ -100,14 +116,22 @@ public class DeploymentArtifactImpl impl m_directives.put(key, value); } + @Override public String getDirective(String key) { return m_directives.get(key); } + @Override public String[] getKeys() { return m_directives.keySet().toArray(new String[m_directives.size()]); } + @Override + public long getSize() { + return m_size; + } + + @Override public String getUrl() { return m_url; } @@ -123,7 +147,7 @@ public class DeploymentArtifactImpl impl boolean result = true; result &= getUrl().equals(dai.getUrl()); - + result &= (getSize() == dai.getSize()); result &= (getKeys().length == dai.getKeys().length); for (String key : getKeys()) { @@ -136,8 +160,11 @@ public class DeploymentArtifactImpl impl @Override public int hashCode() { int result = getUrl().hashCode(); + // + result ^= (int) (m_size ^ (m_size >>> 32)); + ; - for (String key : getKeys()) { + for (String key : m_directives.keySet()) { result ^= getDirective(key).hashCode(); } @@ -149,9 +176,9 @@ public class DeploymentArtifactImpl impl StringBuilder result = new StringBuilder(getUrl() + " [ "); for (String key : getKeys()) { result.append(key) - .append(": ") - .append(getDirective(key)) - .append(" "); + .append(": ") + .append(getDirective(key)) + .append(" "); } result.append("]"); Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/DeploymentVersionRepositoryImpl.java Mon Sep 30 12:00:26 2013 @@ -113,8 +113,8 @@ public class DeploymentVersionRepository return result; } - public DeploymentArtifact createDeploymentArtifact(String url, Map directives) { - DeploymentArtifactImpl result = new DeploymentArtifactImpl(url); + public DeploymentArtifact createDeploymentArtifact(String url, long size, Map directives) { + DeploymentArtifactImpl result = new DeploymentArtifactImpl(url, size); for (Map.Entry entry : directives.entrySet()) { result.addDirective(entry.getKey(), entry.getValue()); } Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java Mon Sep 30 12:00:26 2013 @@ -54,7 +54,6 @@ import org.apache.ace.client.repository. import org.apache.ace.client.repository.repository.Feature2DistributionAssociationRepository; import org.apache.ace.client.repository.repository.FeatureRepository; import org.apache.ace.client.repository.repository.TargetRepository; -import org.apache.ace.client.repository.stateful.impl.StatefulTargetRepositoryImpl; import org.apache.ace.connectionfactory.ConnectionFactory; import org.apache.ace.repository.Repository; import org.apache.ace.repository.ext.BackupRepository; Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java Mon Sep 30 12:00:26 2013 @@ -60,6 +60,11 @@ public interface ArtifactObject extends * Holds a human-readable description for this artifact. */ public static final String KEY_ARTIFACT_DESCRIPTION = "artifactDescription"; + /** + * Key to be used in the ArtifactObject's attributes. + * Holds the (estimated) size, in bytes, for this artifact. + */ + public static final String KEY_SIZE = "artifactSize"; public static final String TOPIC_ENTITY_ROOT = ArtifactObject.class.getSimpleName() + "/"; @@ -112,6 +117,10 @@ public interface ArtifactObject extends */ public String getDescription(); /** + * Returns an (estimated) size, in bytes, for this object, can be -1L if no size is known. + */ + public long getSize(); + /** * Sets a description for this artifact. */ public void setDescription(String value); Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java Mon Sep 30 12:00:26 2013 @@ -54,6 +54,11 @@ public interface DeploymentArtifact { * @return the URL for this deployment artifact. */ public String getUrl(); + + /** + * @return the (estimated) size of this deployment artifact, in bytes. + */ + public long getSize(); /** * @param key A key String, such as the DIRECTIVE_ constants in Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/DeploymentVersionRepository.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/DeploymentVersionRepository.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/DeploymentVersionRepository.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/DeploymentVersionRepository.java Mon Sep 30 12:00:26 2013 @@ -42,5 +42,5 @@ public interface DeploymentVersionReposi * @param directives A map of directives to be packed into the object. * @return The newly created deployment artifact object. */ - public DeploymentArtifact createDeploymentArtifact(String url, Map directives); + public DeploymentArtifact createDeploymentArtifact(String url, long size, Map directives); } Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java?rev=1527522&r1=1527521&r2=1527522&view=diff ============================================================================== --- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java (original) +++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/stateful/impl/StatefulTargetRepositoryImpl.java Mon Sep 30 12:00:26 2013 @@ -568,7 +568,7 @@ public class StatefulTargetRepositoryImp directives.put(DeploymentArtifact.REPOSITORY_PATH, repositoryPath); } - result.add(m_deploymentRepository.createDeploymentArtifact(bundle.getURL(), directives)); + result.add(m_deploymentRepository.createDeploymentArtifact(bundle.getURL(), bundle.getSize(), directives)); } for (ArtifactObject artifact : artifacts.keySet()) { @@ -584,7 +584,7 @@ public class StatefulTargetRepositoryImp directives.put(DeploymentArtifact.REPOSITORY_PATH, repositoryPath); } result.add(m_deploymentRepository.createDeploymentArtifact( - m_artifactRepository.preprocessArtifact(artifact, to, targetID, version), directives)); + m_artifactRepository.preprocessArtifact(artifact, to, targetID, version), artifact.getSize(), directives)); } return result.toArray(new DeploymentArtifact[result.size()]);