You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ma...@apache.org on 2013/04/04 11:43:37 UTC
svn commit: r1464402 [3/11] - in /ace/trunk: org.apache.ace.deployment.api/
org.apache.ace.deployment.deploymentadmin/ org.apache.ace.deployment.itest/
org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/
org.apache.ace.deployment.provider...
Added: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/streamgenerator/impl/StreamGeneratorImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/streamgenerator/impl/StreamGeneratorImpl.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/streamgenerator/impl/StreamGeneratorImpl.java (added)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/streamgenerator/impl/StreamGeneratorImpl.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.streamgenerator.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.ref.SoftReference;
+import java.net.URLConnection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+import org.apache.ace.connectionfactory.ConnectionFactory;
+import org.apache.ace.deployment.provider.ArtifactData;
+import org.apache.ace.deployment.provider.DeploymentProvider;
+import org.apache.ace.deployment.streamgenerator.StreamGenerator;
+
+/**
+ * Stream generator for deployment packages. Communicates with a data provider to get the meta data for the streams. Part of the
+ * meta
+ */
+public class StreamGeneratorImpl implements StreamGenerator {
+ private volatile DeploymentProvider m_provider;
+ private volatile ConnectionFactory m_connectionFactory;
+
+ /**
+ * Returns an input stream with the requested deployment package.
+ *
+ * @param id the ID of the package
+ * @param version the version of the package
+ * @return an input stream
+ * @throws java.io.IOException when the stream could not be generated
+ */
+ public InputStream getDeploymentPackage(String id, String version) throws IOException {
+ List<ArtifactData> data = m_provider.getBundleData(id, version);
+ Manifest manifest = new Manifest();
+ Attributes main = manifest.getMainAttributes();
+
+ main.putValue("Manifest-Version", "1.0");
+ main.putValue("DeploymentPackage-SymbolicName", id);
+ main.putValue("DeploymentPackage-Version", version);
+
+ // Note: getEntries() returns a map. This means that the order of the entries
+ // in the manifest is _not_ defined; this should be fine, as far as the
+ // deployment admin spec goes.
+ for (ArtifactData bd : data) {
+ manifest.getEntries().put(bd.getFilename(), bd.getManifestAttributes(false));
+ }
+
+ return DeploymentPackageStream.createStreamForThread(m_connectionFactory, manifest, data.iterator(), false);
+ }
+
+ /**
+ * Returns an input stream with the requested deployment fix package.
+ *
+ * @param id the ID of the package.
+ * @param fromVersion the version of the target.
+ * @param toVersion the version the target should be in after applying the package.
+ * @return an input stream.
+ * @throws java.io.IOException when the stream could not be generated.
+ */
+ public InputStream getDeploymentPackage(String id, String fromVersion, String toVersion) throws IOException {
+ //return execute(new WorkerFixPackage(id, fromVersion, toVersion));
+ List<ArtifactData> data = m_provider.getBundleData(id, fromVersion, toVersion);
+ Manifest manifest = new Manifest();
+ Attributes main = manifest.getMainAttributes();
+
+ main.putValue("Manifest-Version", "1.0");
+ main.putValue("DeploymentPackage-SymbolicName", id);
+ main.putValue("DeploymentPackage-Version", toVersion);
+ main.putValue("DeploymentPackage-FixPack", "[" + fromVersion + "," + toVersion + ")");
+
+ for (ArtifactData bd : data) {
+ manifest.getEntries().put(bd.getFilename(), bd.getManifestAttributes(true));
+ }
+
+ return DeploymentPackageStream.createStreamForThread(m_connectionFactory, manifest, data.iterator(), true);
+ }
+
+ private static final class DeploymentPackageStream extends InputStream {
+ private byte[] m_readBuffer;
+ private byte[] m_buffer;
+ private JarOutputStream m_output;
+ private Iterator<ArtifactData> m_iter;
+ private InputStream m_current = null;
+ private int m_pos = 0;
+ private int m_max = 0;
+ private boolean m_fixPack;
+
+ private final OutputBuffer m_outputBuffer = new OutputBuffer(this);
+ private final ConnectionFactory m_connectionFactory;
+
+ private DeploymentPackageStream(ConnectionFactory connectionFactory) {
+ this(connectionFactory, 64 * 1024);
+ }
+
+ private DeploymentPackageStream(ConnectionFactory connectionFactory, int bufferSize) {
+ m_connectionFactory = connectionFactory;
+ m_buffer = new byte[bufferSize];
+ m_readBuffer = new byte[bufferSize];
+ }
+
+ private static final ThreadLocal<SoftReference<DeploymentPackageStream>> m_cache = new ThreadLocal<SoftReference<DeploymentPackageStream>>();
+
+ static DeploymentPackageStream createStreamForThread(ConnectionFactory connectionFactory, Manifest man, Iterator<ArtifactData> iter, boolean fixpack) throws IOException {
+ SoftReference<DeploymentPackageStream> ref = m_cache.get();
+ DeploymentPackageStream dps = null;
+ if (ref != null) {
+ dps = ref.get();
+ }
+
+ if (dps == null) {
+ dps = new DeploymentPackageStream(connectionFactory);
+ m_cache.set(new SoftReference<DeploymentPackageStream>(dps));
+ }
+
+ if (dps.isInUse()) {
+ dps = new DeploymentPackageStream(connectionFactory);
+ }
+
+ dps.init(man, iter, fixpack);
+
+ return dps;
+ }
+
+ private boolean isInUse() {
+ return m_output == null;
+ }
+
+ private void init(Manifest man, Iterator<ArtifactData> iter, boolean fixPack) throws IOException {
+ m_max = 0;
+ m_pos = 0;
+ m_output = new JarOutputStream(m_outputBuffer, man);
+ m_output.flush();
+ m_iter = iter;
+ m_fixPack = fixPack;
+ next();
+ }
+
+ private void next() throws IOException {
+ ArtifactData current = (m_iter.hasNext()) ? m_iter.next() : null;
+
+ if (current == null) {
+ m_output.close();
+ }
+ else if (!m_fixPack || current.hasChanged()) {
+ m_current = openStream(current);
+ m_output.putNextEntry(new ZipEntry(current.getFilename()));
+ }
+ else {
+ next();
+ }
+ }
+
+ private InputStream openStream(ArtifactData data) throws IOException {
+ URLConnection conn = m_connectionFactory.createConnection(data.getUrl());
+ return conn.getInputStream();
+ }
+
+ @Override
+ public int read() throws IOException {
+ while (m_pos == m_max) {
+ if (m_current == null) {
+ if (m_output != null) {
+ m_output.close();
+ }
+ m_output = null;
+ m_iter = null;
+ return -1;
+ }
+ m_pos = 0;
+ m_max = 0;
+ int len = m_current.read(m_readBuffer);
+ if (len != -1) {
+ m_output.write(m_readBuffer, 0, len);
+ m_output.flush();
+ }
+ else {
+ try {
+ m_current.close();
+ }
+ catch (Exception ex) {
+ // Not much we can do
+ }
+ m_current = null;
+ m_output.closeEntry();
+ m_output.flush();
+ next();
+ }
+ }
+
+ return m_buffer[m_pos++] & 0xFF;
+ }
+
+ void write(int b) {
+ if (m_max == m_buffer.length) {
+ byte[] tmp = new byte[m_buffer.length + 8192];
+ System.arraycopy(m_buffer, 0, tmp, 0, m_buffer.length);
+ m_buffer = tmp;
+ }
+ m_buffer[m_max++] = (byte) b;
+ }
+
+ @Override
+ public void close() {
+ if (m_output != null) {
+ try {
+ m_output.close();
+ m_output = null;
+ }
+ catch (Exception ex) {
+ // Not much we can do
+ }
+ }
+ if (m_current != null) {
+ try {
+ m_current.close();
+ m_current = null;
+ }
+ catch (Exception ex) {
+ // Not much we can do
+ }
+ }
+ m_iter = null;
+ }
+
+ private static final class OutputBuffer extends OutputStream {
+ private final DeploymentPackageStream m_stream;
+
+ public OutputBuffer(DeploymentPackageStream stream) {
+ m_stream = stream;
+ }
+
+ @Override
+ public void write(int b) {
+ m_stream.write(b);
+ }
+ }
+ }
+}
\ No newline at end of file
Added: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/streamgenerator/packageinfo
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/streamgenerator/packageinfo?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/streamgenerator/packageinfo (added)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/streamgenerator/packageinfo Thu Apr 4 09:43:34 2013
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
Added: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/Activator.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/Activator.java (added)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/Activator.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.task;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.ace.deployment.service.DeploymentService;
+import org.apache.ace.scheduler.constants.SchedulerConstants;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.log.LogService;
+
+public class Activator extends DependencyActivatorBase implements ManagedServiceFactory {
+
+ private static final String PID_NAME = "org.apache.ace.deployment.task.default.factory";
+
+ private static final String MA_NAME = "ma";
+ private static final String DEFAULT_INTERVAL = "5000";
+
+ private final Map<String, List<Component>> m_instances = new HashMap<String, List<Component>>();
+
+ private volatile DependencyManager m_manager;
+
+ /**
+ * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
+ */
+ public void deleted(String pid) {
+ List<Component> components;
+ synchronized (m_instances) {
+ components = m_instances.remove(pid);
+ }
+ if (components != null) {
+ for (Component component : components) {
+ m_manager.remove(component);
+ }
+ }
+ }
+
+ /**
+ * @see org.apache.felix.dm.DependencyActivatorBase#destroy(org.osgi.framework.BundleContext, org.apache.felix.dm.DependencyManager)
+ */
+ public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+ // do nothing
+ }
+
+ /**
+ * @see org.osgi.service.cm.ManagedServiceFactory#getName()
+ */
+ public String getName() {
+ return "Deployment Service - default check/update tasks";
+ }
+
+ /**
+ * @see org.apache.felix.dm.DependencyActivatorBase#init(org.osgi.framework.BundleContext, org.apache.felix.dm.DependencyManager)
+ */
+ public void init(BundleContext context, DependencyManager manager) throws Exception {
+ m_manager = manager;
+
+ List<Component> components = createServices(null);
+ for (Component component : components) {
+ m_manager.add(component);
+ }
+
+ Properties props = new Properties();
+ props.put(Constants.SERVICE_PID, PID_NAME);
+
+ manager.add(createComponent()
+ .setInterface(ManagedServiceFactory.class.getName(), props)
+ .setImplementation(this)
+ );
+ }
+
+ /**
+ * @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String, java.util.Dictionary)
+ */
+ public void updated(String pid, Dictionary dict) throws ConfigurationException {
+ String ma = (String) dict.get(MA_NAME);
+
+ List<Component> components = m_instances.get(pid);
+ if (components == null) {
+ components = createServices(ma);
+ synchronized (m_instances) {
+ m_instances.put(pid, components);
+ }
+ for (Component component : components) {
+ m_manager.add(component);
+ }
+ }
+ else {
+ // TODO do we want to deal with changes here?
+ }
+ }
+
+ /**
+ * Creates the check/update task components for the given management agent name.
+ *
+ * @param ma the name of the management agent to create the service for, can be <code>null</code>.
+ * @return an array with {@link Component} instances for the different tasks, never <code>null</code>.
+ */
+ private List<Component> createServices(String ma) {
+ Dictionary updateProperties = new Properties();
+ Dictionary checkProperties = new Properties();
+ Dictionary deploymentProperties = new Properties();
+
+ String updateSchedulerName = DeploymentUpdateTask.class.getName();
+ String updateDescription = "Task that synchronizes the artifacts (bundles, resources) installed on this target with the server.";
+
+ String checkSchedulerName = DeploymentCheckTask.class.getName();
+ String checkDescription = "Task that checks for updates of artifacts installed on this target with the server.";
+
+ String deploymentFilter = "(" + Constants.OBJECTCLASS + "=" + DeploymentService.class.getName() + ")";
+
+ if (ma == null || "".equals(ma)) {
+ deploymentFilter = String.format("(&%s(!(%s=*)))", deploymentFilter, MA_NAME);
+ }
+ else {
+ updateSchedulerName = "ma=" + ma + ";name=" + updateSchedulerName;
+ updateDescription = "Task that synchronizes the artifacts (bundles, resources) installed on this target with the server with ma=" + ma + ".";
+
+ checkSchedulerName = "ma=" + ma + ";name=" + checkSchedulerName;
+ checkDescription = "Task that checks for updates of artifacts installed on this target with the server with ma=" + ma + ".";
+
+ deploymentFilter = String.format("(&%s(%s=%s))", deploymentFilter, MA_NAME, ma);
+
+ updateProperties.put(MA_NAME, ma);
+ checkProperties.put(MA_NAME, ma);
+ deploymentProperties.put(MA_NAME, ma);
+ }
+
+ List<Component> result = new ArrayList<Component>();
+
+ updateProperties.put(SchedulerConstants.SCHEDULER_NAME_KEY, updateSchedulerName);
+ updateProperties.put(SchedulerConstants.SCHEDULER_DESCRIPTION_KEY, updateDescription);
+ updateProperties.put(SchedulerConstants.SCHEDULER_RECIPE, DEFAULT_INTERVAL);
+
+ DeploymentUpdateTask updateTask = new DeploymentUpdateTask();
+
+ Component updateTaskComponent =
+ createComponent()
+ .setInterface(Runnable.class.getName(), updateProperties)
+ .setImplementation(updateTask)
+ .add(createServiceDependency().setService(DeploymentService.class, deploymentFilter).setRequired(true))
+ .add(createServiceDependency().setService(LogService.class).setRequired(false));
+
+ checkProperties.put(SchedulerConstants.SCHEDULER_NAME_KEY, checkSchedulerName);
+ checkProperties.put(SchedulerConstants.SCHEDULER_DESCRIPTION_KEY, checkDescription);
+ checkProperties.put(SchedulerConstants.SCHEDULER_RECIPE, DEFAULT_INTERVAL);
+
+ result.add(updateTaskComponent);
+
+ DeploymentCheckTask checkTask = new DeploymentCheckTask();
+
+ Component checkTaskComponent =
+ createComponent()
+ .setInterface(Runnable.class.getName(), checkProperties)
+ .setImplementation(checkTask)
+ .add(createServiceDependency().setService(DeploymentService.class, deploymentFilter).setRequired(true))
+ .add(createServiceDependency().setService(EventAdmin.class).setRequired(false))
+ .add(createServiceDependency().setService(LogService.class).setRequired(false));
+
+ result.add(checkTaskComponent);
+
+ return result;
+ }
+}
\ No newline at end of file
Added: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/DeploymentCheckTask.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/DeploymentCheckTask.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/DeploymentCheckTask.java (added)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/DeploymentCheckTask.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.task;
+
+import java.net.MalformedURLException;
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.apache.ace.deployment.service.DeploymentService;
+import org.osgi.framework.Version;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.log.LogService;
+
+/**
+ * Task that checks for a new version and sends out an event if there is a new version. It does not actually
+ * download or install it.
+ */
+public class DeploymentCheckTask implements Runnable {
+
+ private static final String TOPIC_UPDATE_AVAILABLE = "org/apache/ace/deployment/UPDATEAVAILABLE";
+
+ private volatile LogService m_log;
+ private volatile EventAdmin m_eventAdmin;
+ private volatile DeploymentService m_service;
+
+ /**
+ * When run a check is made if a higher version is available on the remote. If so, send out an event.
+ */
+ public void run() {
+ try {
+ Version localVersion = m_service.getHighestLocalVersion();
+ Version remoteVersion = m_service.getHighestRemoteVersion();
+
+ if (remoteVersion == null) {
+ // expected if there's no discovered ps or relay server
+ // ACE-220: lower log level; not of real interest...
+ m_log.log(LogService.LOG_DEBUG, "Highest remote: unknown / Highest local: " + localVersion);
+ return;
+ }
+
+ // ACE-220: lower log level; not of real interest...
+ m_log.log(LogService.LOG_DEBUG, "Highest remote: " + remoteVersion + " / Highest local: " + localVersion);
+
+ if ((remoteVersion != null) && ((localVersion == null) || (remoteVersion.compareTo(localVersion) > 0))) {
+ m_eventAdmin.postEvent(createEvent(localVersion, remoteVersion));
+ }
+ }
+ catch (MalformedURLException e) {
+ m_log.log(LogService.LOG_ERROR, "Error creating endpoint url", e);
+ }
+ catch (Exception e) {
+ m_log.log(LogService.LOG_ERROR, "Error checking for update", e);
+ }
+ }
+
+ /**
+ * Creates an event for notifying listeners that a new version can be installed.
+ *
+ * @param localVersion the highest local version;
+ * @param remoteVersion the higest remote version.
+ * @return a new {@link Event} instance, never <code>null</code>.
+ */
+ private Event createEvent(Version localVersion, Version remoteVersion) {
+ Properties properties = new Properties();
+ properties.put("deploymentpackage.localversion", ((localVersion == null) ? Version.emptyVersion : localVersion));
+ properties.put("deploymentpackage.remoteversion", remoteVersion);
+
+ return new Event(TOPIC_UPDATE_AVAILABLE, (Dictionary) properties);
+ }
+}
\ No newline at end of file
Added: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/DeploymentUpdateTask.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/DeploymentUpdateTask.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/DeploymentUpdateTask.java (added)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/task/DeploymentUpdateTask.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.task;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.apache.ace.deployment.service.DeploymentService;
+import org.osgi.framework.Version;
+import org.osgi.service.log.LogService;
+
+/**
+ * Implementation of the <code>Runnable</code> interface that updates software configurations by using the
+ * <code>DeploymentService</code> to determine the current local version and to actually install new versions.
+ */
+public class DeploymentUpdateTask implements Runnable {
+
+ private volatile DeploymentService m_service;
+ private volatile LogService m_log;
+
+ /**
+ * When run a check is made if a higher version is available on the remote. If so, an attempt is made to install
+ * this new version.
+ */
+ public void run() {
+ try {
+ Version highestLocalVersion = m_service.getHighestLocalVersion();
+ Version highestRemoteVersion = m_service.getHighestRemoteVersion();
+
+ if (highestRemoteVersion == null) {
+ // expected if there's no discovered ps or relay server
+ // ACE-220: lower log level; not of real interest...
+ m_log.log(LogService.LOG_DEBUG, "Highest remote: unknown / Highest local: " + highestLocalVersion);
+ return;
+ }
+ // ACE-220: lower log level; not of real interest...
+ m_log.log(LogService.LOG_DEBUG, "Highest remote: " + highestRemoteVersion + " / Highest local: " + highestLocalVersion);
+
+ if ((highestRemoteVersion != null) && ((highestLocalVersion == null) || (highestRemoteVersion.compareTo(highestLocalVersion) > 0))) {
+ // no local version or local version lower than remote, install the update
+ m_service.installVersion(highestRemoteVersion, highestLocalVersion);
+ }
+ }
+ catch (MalformedURLException e) {
+ m_log.log(LogService.LOG_ERROR, "Error creating endpoint url", e);
+ }
+ catch (IOException e) {
+ m_log.log(LogService.LOG_ERROR, "Error accessing resources", e);
+ }
+ catch (Exception e) {
+ m_log.log(LogService.LOG_ERROR, "Error installing update", e);
+ }
+ }
+}
\ No newline at end of file
Added: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/BundleStreamGenerator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/BundleStreamGenerator.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/BundleStreamGenerator.java (added)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/BundleStreamGenerator.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.util.test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.apache.ace.deployment.provider.ArtifactData;
+import org.osgi.framework.Constants;
+
+public class BundleStreamGenerator {
+
+ public static Manifest getBundleManifest(String symbolicname, String version, Map<String, String> additionalHeaders) {
+ Manifest manifest = new Manifest();
+ manifest.getMainAttributes().putValue("Manifest-Version", "1");
+ manifest.getMainAttributes().putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
+ manifest.getMainAttributes().putValue(Constants.BUNDLE_SYMBOLICNAME, symbolicname);
+ manifest.getMainAttributes().putValue(Constants.BUNDLE_VERSION, version.toString());
+ for (Map.Entry<String, String> entry : additionalHeaders.entrySet()) {
+ manifest.getMainAttributes().putValue(entry.getKey(), entry.getValue());
+ }
+ return manifest;
+ }
+
+ public static void generateBundle(ArtifactData data, Map<String, String> additionalHeaders) throws IOException {
+ OutputStream bundleStream = null;
+ try {
+ File dataFile = new File(data.getUrl().toURI());
+ OutputStream fileStream = new FileOutputStream(dataFile);
+ bundleStream = new JarOutputStream(fileStream, getBundleManifest(data.getSymbolicName(), data.getVersion(), additionalHeaders));
+ bundleStream.flush();
+ } catch (URISyntaxException e) {
+ throw new IOException();
+ } finally {
+ if (bundleStream != null) {
+ bundleStream.close();
+ }
+ }
+ }
+
+ public static void generateBundle(ArtifactData data) throws IOException {
+ generateBundle(data, new HashMap<String, String>());
+ }
+}
Added: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/TestData.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/TestData.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/TestData.java (added)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/TestData.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.util.test;
+
+import java.net.URL;
+import java.util.jar.Attributes;
+
+import org.apache.ace.deployment.provider.ArtifactData;
+
+public class TestData implements ArtifactData {
+ private final String m_fileName;
+ private final String m_symbolicName;
+ private final URL m_url;
+ private final String m_version;
+ private final boolean m_changed;
+
+ public TestData(String fileName, String symbolicName, URL url, String version, boolean changed) {
+ m_fileName = fileName;
+ m_symbolicName = symbolicName;
+ m_url = url;
+ m_version = version;
+ m_changed = changed;
+ }
+
+ public boolean hasChanged() {
+ return m_changed;
+ }
+
+ public String getFilename() {
+ return m_fileName;
+ }
+
+ public String getSymbolicName() {
+ return m_symbolicName;
+ }
+
+ public URL getUrl() {
+ return m_url;
+ }
+
+ public String getVersion() {
+ return m_version;
+ }
+
+ public String getDirective() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Attributes getManifestAttributes(boolean fixPackage) {
+ Attributes a = new Attributes();
+ a.putValue("Bundle-SymbolicName", getSymbolicName());
+ a.putValue("Bundle-Version", getVersion());
+ return a;
+ }
+
+ public String getProcessorPid() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isBundle() {
+ return true;
+ }
+
+ public boolean isCustomizer() {
+ return false;
+ }
+}
Added: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/TestProvider.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/TestProvider.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/TestProvider.java (added)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/TestProvider.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.util.test;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.ace.deployment.provider.ArtifactData;
+import org.apache.ace.deployment.provider.DeploymentProvider;
+
+public class TestProvider implements DeploymentProvider {
+ private List<ArtifactData> m_collection;
+ private List<String> m_versions;
+
+ public TestProvider() throws Exception {
+ m_collection = new ArrayList<ArtifactData>();
+ m_versions = new ArrayList<String>();
+ }
+
+ public void addData(String fileName, String symbolicName, URL url, String version) {
+ addData(fileName, symbolicName, url, version, true);
+ }
+
+ public void addData(String fileName, String symbolicName, URL url, String version, boolean changed) {
+ m_collection.add(new TestData(fileName, symbolicName, url, version, changed));
+ m_versions.add(version);
+ }
+
+ public List<ArtifactData> getBundleData(String id, String version) {
+ return m_collection;
+ }
+
+ public List<ArtifactData> getBundleData(String id, String versionFrom, String versionTo) {
+ return m_collection;
+ }
+
+ public List<String> getVersions(String id) throws IllegalArgumentException {
+ Collections.sort(m_versions);
+ return m_versions;
+ }
+}
Added: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/packageinfo
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/packageinfo?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/packageinfo (added)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/util/test/packageinfo Thu Apr 4 09:43:34 2013
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
Added: ace/trunk/org.apache.ace.deployment/streamgenerator.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/streamgenerator.bnd?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/streamgenerator.bnd (added)
+++ ace/trunk/org.apache.ace.deployment/streamgenerator.bnd Thu Apr 4 09:43:34 2013
@@ -0,0 +1,4 @@
+Private-Package: org.apache.ace.deployment.streamgenerator.impl
+Bundle-Activator: org.apache.ace.deployment.streamgenerator.impl.Activator
+Export-Package: org.apache.ace.deployment.streamgenerator
+Bundle-Version: 1.0.0
Added: ace/trunk/org.apache.ace.deployment/task.base.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/task.base.bnd?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/task.base.bnd (added)
+++ ace/trunk/org.apache.ace.deployment/task.base.bnd Thu Apr 4 09:43:34 2013
@@ -0,0 +1,4 @@
+Private-Package: org.apache.ace.deployment.service.impl
+Bundle-Activator: org.apache.ace.deployment.service.impl.Activator
+Export-Package: org.apache.ace.deployment.service
+Bundle-Version: 1.0.0
Added: ace/trunk/org.apache.ace.deployment/task.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/task.bnd?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/task.bnd (added)
+++ ace/trunk/org.apache.ace.deployment/task.bnd Thu Apr 4 09:43:34 2013
@@ -0,0 +1,3 @@
+Private-Package: org.apache.ace.deployment.task
+Bundle-Activator: org.apache.ace.deployment.task.Activator
+Bundle-Version: 1.0.0
Added: ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/DeploymentTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/DeploymentTest.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/DeploymentTest.java (added)
+++ ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/DeploymentTest.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment;
+
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+
+import java.io.InputStream;
+
+import org.apache.ace.deployment.deploymentadmin.DeploymentAdminDeployer;
+import org.apache.ace.test.utils.TestUtils;
+import org.osgi.framework.Version;
+import org.osgi.service.deploymentadmin.DeploymentAdmin;
+import org.osgi.service.deploymentadmin.DeploymentPackage;
+import org.osgi.service.log.LogService;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+public class DeploymentTest {
+
+ private DeploymentAdminDeployer m_deploymentAdminDeployer;
+ private DeploymentPackage m_mockDeploymentPackage;
+
+ private static final String MOCK_NAME = "MockName";
+ private static final Version MOCK_VERSION = new Version("0.1");
+
+ @BeforeTest(alwaysRun = true)
+ protected void setUp() throws Exception {
+ m_deploymentAdminDeployer = new DeploymentAdminDeployer();
+ TestUtils.configureObject(m_deploymentAdminDeployer, LogService.class);
+ Object mockDeploymentAdmin = TestUtils.createMockObjectAdapter(DeploymentAdmin.class, new MockDeploymentAdmin());
+ TestUtils.configureObject(m_deploymentAdminDeployer, DeploymentAdmin.class, mockDeploymentAdmin);
+ m_mockDeploymentPackage = TestUtils.createMockObjectAdapter(DeploymentPackage.class, new MockDeploymentPackage());
+ }
+
+ @Test(groups = { UNIT })
+ public void testDeployment() throws Exception {
+ Object deploymentPackage = m_deploymentAdminDeployer.install(null);
+ assert m_deploymentAdminDeployer.getName(deploymentPackage).equals(MOCK_NAME) : "Installation of mock deployment package failed";
+ assert m_deploymentAdminDeployer.getVersion(deploymentPackage).equals(MOCK_VERSION) : "Installation of mock deployment package failed";
+ assert ((DeploymentPackage) m_deploymentAdminDeployer.list()[0]).getName().equals(MOCK_NAME) : "List result does not match expected result";
+ boolean exceptionthrown = false;
+ try {
+ m_deploymentAdminDeployer.getName(new String("illegalargument"));
+ } catch (IllegalArgumentException iae) {
+ exceptionthrown = true;
+ }
+ assert exceptionthrown : "Illegal argument for getName() did not throw exception";
+ exceptionthrown = false;
+ try {
+ m_deploymentAdminDeployer.getVersion(new String("illegalargument"));
+ } catch (IllegalArgumentException iae) {
+ exceptionthrown = true;
+ }
+ assert exceptionthrown : "Illegal argument for getVersion() did not throw exception";
+ }
+
+ private class MockDeploymentAdmin {
+ public DeploymentPackage installDeploymentPackage(InputStream is) {
+ return m_mockDeploymentPackage;
+ }
+
+ public DeploymentPackage[] listDeploymentPackages() {
+ return new DeploymentPackage[] {m_mockDeploymentPackage};
+ }
+ }
+
+ private class MockDeploymentPackage {
+ public String getName() {
+ return MOCK_NAME;
+ }
+
+ public Version getVersion() {
+ return MOCK_VERSION;
+ }
+ }
+}
Added: ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/filebased/FileBasedProviderTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/filebased/FileBasedProviderTest.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/filebased/FileBasedProviderTest.java (added)
+++ ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/filebased/FileBasedProviderTest.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,292 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.provider.filebased;
+
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.ace.deployment.provider.ArtifactData;
+import org.apache.ace.deployment.provider.impl.ArtifactDataImpl;
+import org.apache.ace.deployment.util.test.BundleStreamGenerator;
+import org.apache.ace.test.utils.FileUtils;
+import org.apache.ace.test.utils.TestUtils;
+import org.osgi.service.log.LogService;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+/**
+ * This test class tests the FileBasedProvider class.
+ * This class implements 2 backend interfaces,
+ * and both are tested here.
+ */
+public class FileBasedProviderTest {
+
+ private FileBasedProvider m_backend;
+
+ private File m_tempDirectory;
+
+ private final String VERSION1 = "1.0.0";
+ private final String VERSION2 = "2.0.0";
+ private final String VERSION3 = "3.0.0";
+ private final String VERSION4 = "4.0.0";
+ private final String INVALIDVERSION = "Invalid.version.directory";
+
+ private final String TARGET = "target";
+ private final String MULTIPLEVERSIONTARGET = "multi-version-target";
+ private final String INVALIDVERSIONTARGET = "illegal-version-target";
+ private ArtifactData BUNDLE1;
+ private ArtifactData BUNDLE3;
+ private ArtifactData BUNDLE4;
+ private ArtifactData BUNDLE4_1;
+ private ArtifactData BUNDLE5;
+ private ArtifactData BUNDLE3_2;
+ private ArtifactData BUNDLE4_2;
+
+ @SuppressWarnings("serial")
+ @BeforeTest(alwaysRun = true)
+ protected void setUp() throws Exception {
+
+ // first create a file
+ m_tempDirectory = FileUtils.createTempFile(null);
+ // and make a directory with that name.
+ m_tempDirectory.mkdir();
+ setupSampleData();
+
+ m_backend = new FileBasedProvider();
+ TestUtils.configureObject(m_backend, LogService.class);
+ m_backend.updated(new Properties() {{put("BaseDirectoryName", m_tempDirectory.getAbsolutePath());}});
+ }
+
+ /**
+ * make a bundle with the given symbolic name and version in the given file.
+ */
+ private ArtifactData generateBundle(File file, String symbolicName, String version) throws Exception {
+ ArtifactData bundle = new ArtifactDataImpl(file.getName(), symbolicName, version, file.toURI().toURL(), false);
+ BundleStreamGenerator.generateBundle(bundle);
+ return bundle;
+ }
+
+ /**
+ * Create the test targets, versions and testbundles..
+ */
+ private void setupSampleData() throws Exception {
+ File target = new File(m_tempDirectory, TARGET);
+ target.mkdirs();
+ File targetVersion1 = new File(target, VERSION1);
+ targetVersion1.mkdirs();
+ BUNDLE1 = generateBundle(FileUtils.createTempFile(targetVersion1), "Bundle1", "1.0.0");
+
+ File illegalVersionTarget = new File(m_tempDirectory, INVALIDVERSIONTARGET);
+ illegalVersionTarget.mkdirs();
+ File faultyVersion = new File(illegalVersionTarget, INVALIDVERSION);
+ faultyVersion.mkdirs();
+ // this bundle should never be accessed
+ generateBundle(FileUtils.createTempFile(faultyVersion), "Bundle2", "2.0.0");
+
+ File multipleVersionTarget = new File(m_tempDirectory, MULTIPLEVERSIONTARGET);
+ multipleVersionTarget.mkdir();
+ File multipleVersionTargetVersion1 = new File(multipleVersionTarget, VERSION1);
+ multipleVersionTargetVersion1.mkdir();
+ BUNDLE3 = generateBundle(FileUtils.createTempFile(multipleVersionTargetVersion1), "Bundle3", "3.0.0");
+ BUNDLE4 = generateBundle(FileUtils.createTempFile(multipleVersionTargetVersion1), "Bundle4", "4.0.0");
+ File multipleVersionTargetVersion2 = new File(multipleVersionTarget, VERSION2);
+ multipleVersionTargetVersion2.mkdir();
+ BUNDLE4_1 = generateBundle(FileUtils.createTempFile(multipleVersionTargetVersion2), "Bundle4", "4.1.0");
+ BUNDLE5 = generateBundle(FileUtils.createTempFile(multipleVersionTargetVersion2), "Bundle5", "5.0.0");
+ File multipleVersionTargetVersion3 = new File(multipleVersionTarget, VERSION3);
+ multipleVersionTargetVersion3.mkdir();
+ File multipleVersionTargetVersion4 = new File(multipleVersionTarget, VERSION4);
+ multipleVersionTargetVersion4.mkdir();
+ BUNDLE3_2 = generateBundle(FileUtils.createTempFile(multipleVersionTargetVersion4), "Bundle3", "3.0.0");
+ BUNDLE4_2 = generateBundle(FileUtils.createTempFile(multipleVersionTargetVersion4), "Bundle4", "5.0.0");
+ }
+
+ /**
+ * See if the getVersions() methods normal output works
+ */
+ @Test(groups = { UNIT })
+ public void testGetVersion() {
+ List<String> versions = m_backend.getVersions(TARGET);
+ assert versions.size() == 1 : "Expected one version to be found, but found " + versions.size();
+ assert versions.get(0).equals(VERSION1) : "Expected version " + VERSION1 + " but found " + versions.get(0);
+ }
+
+ /**
+ * Test the getVersions method with an illegal version (not in org.osgi.framework.Version format)
+ */
+ @Test(groups = { UNIT })
+ public void testIllegalVersion() {
+ // an illegal version should be silently ignored
+ List<String> versions = m_backend.getVersions(INVALIDVERSIONTARGET);
+ assert versions.isEmpty() : "Expected no versions to be found, but found " + versions.size();
+ }
+
+ /**
+ * Test with multiple versions. It expects all versions in an ascending order.
+ */
+ @Test(groups = { UNIT })
+ public void testMultipleVersions() {
+ List<String> versions = m_backend.getVersions(MULTIPLEVERSIONTARGET);
+ assert versions.size() == 4 : "Expected three version to be found, but found " + versions.size();
+ // all versions should be in ascending order
+ assert versions.get(0).equals(VERSION1) : "Expected version " + VERSION1 + " but found " + versions.get(0);
+ assert versions.get(1).equals(VERSION2) : "Expected version " + VERSION2 + " but found " + versions.get(1);
+ assert versions.get(2).equals(VERSION3) : "Expected version " + VERSION3 + " but found " + versions.get(2);
+ assert versions.get(3).equals(VERSION4) : "Expected version " + VERSION4 + " but found " + versions.get(3);
+ }
+
+ /**
+ * Test the getBundleData for a single version, returning a single bundle
+ */
+ @Test(groups = { UNIT })
+ public void testSingleBundleSingleVersionBundleData() {
+ Collection<ArtifactData> bundleData = m_backend.getBundleData(TARGET, VERSION1);
+ assert bundleData.size() == 1 : "Expected one bundle to be found, but found " + bundleData.size();
+ assert bundleData.contains(BUNDLE1) : "Expected to find bundle " + BUNDLE1.getSymbolicName();
+ }
+
+ /**
+ * Test the getBundleData for a single version, returning a multiple bundles
+ */
+ @Test(groups = { UNIT })
+ public void testMultipleBundleSingleVersionBundleData() {
+ Collection<ArtifactData> bundleData = m_backend.getBundleData(MULTIPLEVERSIONTARGET, VERSION1);
+ assert bundleData.size() == 2 : "Expected two bundle to be found, but found " + bundleData.size();
+ assert bundleData.contains(BUNDLE3) : "Expected to find bundle " + BUNDLE3.getSymbolicName();
+ assert bundleData.contains(BUNDLE4) : "Expected to find bundle " + BUNDLE4.getSymbolicName();
+ }
+
+ /**
+ * Test the getBundleData with an illegal version (i.e. a version that doesn't exist)
+ */
+ @Test(groups = { UNIT })
+ public void testInvalidVersionBundleData() {
+ try {
+ m_backend.getBundleData(INVALIDVERSIONTARGET, INVALIDVERSION);
+ assert false : "Expected an error because version " + INVALIDVERSION + " doesn't exist for target" + INVALIDVERSIONTARGET;
+ } catch (IllegalArgumentException iae) {
+ // expected, because the version doesn't exist
+ }
+ }
+
+ /**
+ * Test the getBundleData for a two versions, returning a single bundle that hasn't changed
+ */
+ @Test(groups = { UNIT })
+ public void testSingleUnchangedBundleMultipleVersions() {
+ Collection<ArtifactData> bundleData = m_backend.getBundleData(TARGET, VERSION1, VERSION1);
+ assert bundleData.size() == 1 : "Expect one bundle, got " + bundleData.size();
+ Iterator<ArtifactData> it = bundleData.iterator();
+ while(it.hasNext()) {
+ ArtifactData data = it.next();
+ assert !data.hasChanged() : "The data should not have been changed.";
+ }
+ }
+
+ /**
+ * Test the getBundleData for a two versions, returning multiple bundles that haven't changed
+ */
+ @Test(groups = { UNIT })
+ public void testMultipleBundlesMultipleVersions() {
+ Collection<ArtifactData> bundleData = m_backend.getBundleData(MULTIPLEVERSIONTARGET, VERSION1, VERSION1);
+ assert bundleData.size() == 2 : "Expected two bundle to be found, but found " + bundleData.size();
+ Iterator<ArtifactData> it = bundleData.iterator();
+ while(it.hasNext()) {
+ ArtifactData data = it.next();
+ assert !data.hasChanged() : "The data should not have been changed.";
+ }
+ }
+
+ /**
+ * Test the getBundleData for a two versions, where in the second version a bundle is removed
+ */
+ @Test(groups = { UNIT })
+ public void testRemovedBundleMultipleVersions() {
+ Collection<ArtifactData> bundleData = m_backend.getBundleData(MULTIPLEVERSIONTARGET, VERSION1, VERSION3);
+ assert bundleData.size() == 0 : "Expected zero bundle to be found, but found " + bundleData.size();
+ }
+
+ /**
+ * Test the getBundleData for a two versions, where in the second version a bundle is added
+ */
+ @Test(groups = { UNIT })
+ public void testAddedBundleMultipleVersions() {
+ Collection<ArtifactData> bundleData = m_backend.getBundleData(MULTIPLEVERSIONTARGET, VERSION3, VERSION1);
+ assert bundleData.size() == 2 : "Expected two bundle to be found, but found " + bundleData.size();
+ Iterator<ArtifactData> it = bundleData.iterator();
+ while(it.hasNext()) {
+ ArtifactData data = it.next();
+ assert data.hasChanged() : "The data should have been changed.";
+ }
+ }
+
+ /**
+ * Test the getBundleData for a two versions, where in the second version one bundle has changed and another hasn't
+ */
+ @Test(groups = { UNIT })
+ public void testSingleChangedBundleMultipleVersions() {
+ Collection<ArtifactData> bundleData = m_backend.getBundleData(MULTIPLEVERSIONTARGET, VERSION1, VERSION4);
+ assert bundleData.size() == 2 : "Expected one bundle to be found, but found " + bundleData.size();
+ Iterator<ArtifactData> it = bundleData.iterator();
+ while(it.hasNext()) {
+ ArtifactData data = it.next();
+ if (data.equals(BUNDLE3_2)) {
+ assert !data.hasChanged() : "The data should not have been changed.";
+ } else if (data.equals(BUNDLE4_2)) {
+ assert data.hasChanged() : "The data should have been changed.";
+ } else {
+ assert false : "Unknown bundle found";
+ }
+ }
+ }
+
+ /**
+ * Test the getBundleData for a two versions, where two bundles have changed
+ */
+ @Test(groups = { UNIT })
+ public void testMultipleChangedBundlesMultipleVersions() {
+ Collection<ArtifactData> bundleData = m_backend.getBundleData(MULTIPLEVERSIONTARGET, VERSION1, VERSION2);
+ assert bundleData.size() == 2 : "Expected one bundle to be found, but found " + bundleData.size();
+ Iterator<ArtifactData> it = bundleData.iterator();
+ while(it.hasNext()) {
+ ArtifactData data = it.next();
+ if (data.equals(BUNDLE4_1)) {
+ assert data.hasChanged() : "The data should have been changed.";
+ } else if (data.equals(BUNDLE5)) {
+ assert data.hasChanged() : "The data should have been changed.";
+ } else {
+ assert false : "Unknown bundle found";
+ }
+ }
+ }
+
+
+ @AfterTest(alwaysRun = true)
+ public void tearDown() throws Exception {
+ FileUtils.removeDirectoryWithContent(m_tempDirectory);
+ }
+
+
+}
Added: ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/BaseRepositoryHandlerTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/BaseRepositoryHandlerTest.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/BaseRepositoryHandlerTest.java (added)
+++ ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/BaseRepositoryHandlerTest.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,371 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.provider.repositorybased;
+
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.ace.deployment.provider.repositorybased.BaseRepositoryHandler.XmlDeploymentArtifact;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Test cases for {@link BaseRepositoryHandler}.
+ */
+public class BaseRepositoryHandlerTest {
+
+ private static final String TAGS_TAG = "tags";
+ private static final String VERSION_TAG = "version";
+ private static final String TARGETID_TAG = "targetID";
+ private static final String ARTIFACTS_TAG = "artifacts";
+ private static final String ARTIFACT_TAG = "deploymentArtifact";
+ private static final String URL_TAG = "url";
+ private static final String DIRECTIVES_TAG = "directives";
+ private static final String ATTRIBUTES_TAG = "attributes";
+ private static final String DEPLOYMENTVERSION_TAG = "deploymentversion";
+
+ private static final String TARGET = "target";
+ private static final String MULTIPLEVERSIONTARGET = "multi-version-target";
+ private static final String EMPTYVERSIONTARGET = "empty-version-target";
+
+ private static final String VERSION1 = "1.0.0";
+ private static final String VERSION2 = "2.0.0";
+ private static final String VERSION3 = "3.0.0";
+ private static final String VERSION3_2 = "3.2.0";
+ private static final String VERSION4 = "4.0.0";
+ private static final String VERSION4_1 = "4.1.0";
+ private static final String VERSION4_2 = "4.2.0";
+ private static final String VERSION5 = "5.0.0";
+
+ public static final String KEY_SYMBOLICNAME = Constants.BUNDLE_SYMBOLICNAME;
+ public static final String KEY_NAME = Constants.BUNDLE_NAME;
+ public static final String KEY_VERSION = Constants.BUNDLE_VERSION;
+ public static final String KEY_VENDOR = Constants.BUNDLE_VENDOR;
+ public static final String KEY_RESOURCE_PROCESSOR_PID = "Deployment-ProvidesResourceProcessor";
+
+ public static final String MIMETYPE = "application/vnd.osgi.bundle";
+
+
+ private InputStream m_inputStream;
+ private SAXParser m_parser;
+
+ @BeforeMethod(alwaysRun = true)
+ protected void setUp() throws Exception {
+ SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+ m_parser = saxParserFactory.newSAXParser();
+
+ String xml = generateValidTestXml();
+ m_inputStream = new ByteArrayInputStream(xml.getBytes());
+ }
+
+ /**
+ * Tests that a deployment package with a single version can be parsed & found.
+ *
+ * @throws Exception not part of this test case.
+ */
+ @Test(groups = { UNIT })
+ public void testGatherSingleVersionOk() throws Exception {
+ DeploymentPackageVersionCollector handler = new DeploymentPackageVersionCollector(TARGET);
+
+ m_parser.parse(m_inputStream, handler);
+
+ List<Version> versions = handler.getVersions();
+ assert versions.size() == 1 : "Expected a single version to be found!";
+
+ assert Version.parseVersion(VERSION1).equals(versions.get(0)) : "Expected version1 to be found!";
+ }
+
+ /**
+ * Tests that the single artifact of a deployment package with a single version can be parsed & found.
+ *
+ * @throws Exception not part of this test case.
+ */
+ @Test(groups = { UNIT })
+ public void testGatherSingleArtifactOk() throws Exception {
+ DeploymentArtifactCollector handler = new DeploymentArtifactCollector(TARGET, VERSION1);
+
+ m_parser.parse(m_inputStream, handler);
+
+ List<XmlDeploymentArtifact>[] artifacts = handler.getArtifacts();
+ assert artifacts.length == 1 : "Expected a single artifact to be found!";
+ assert artifacts[0].size() == 1 : "Expected a single artifact to be found!";
+
+ XmlDeploymentArtifact artifact1 = artifacts[0].get(0);
+ assert new URL("file:///bundle1").equals(artifact1.getUrl()) : "Expected 'file:///bundle1' URL to be found!";
+ assert artifact1.getDirective().size() == 2 : "Expected two directives to be found!";
+ assert "bundle1".equals(artifact1.getDirective().get(KEY_SYMBOLICNAME)) : "Expected correct symbolic name to be found!";
+ assert "1.0.0".equals(artifact1.getDirective().get(KEY_VERSION)) : "Expected correct bundle version to be found!";
+ }
+
+ /**
+ * Tests that a deployment package with multiple versions can be parsed & found.
+ *
+ * @throws Exception not part of this test case.
+ */
+ @Test(groups = { UNIT })
+ public void testGatherMultipleVersionOk() throws Exception {
+ DeploymentPackageVersionCollector handler = new DeploymentPackageVersionCollector(MULTIPLEVERSIONTARGET);
+
+ m_parser.parse(m_inputStream, handler);
+
+ List<Version> versions = handler.getVersions();
+ assert versions.size() == 4 : "Expected four versions to be found!";
+
+ assert Version.parseVersion(VERSION1).equals(versions.get(0)) : "Expected version1 to be found!";
+ assert Version.parseVersion(VERSION2).equals(versions.get(1)) : "Expected version2 to be found!";
+ assert Version.parseVersion(VERSION3).equals(versions.get(2)) : "Expected version3 to be found!";
+ assert Version.parseVersion(VERSION4).equals(versions.get(3)) : "Expected version4 to be found!";
+ }
+
+ /**
+ * Tests that multiple artifacts of a deployment package with a single version can be parsed & found.
+ *
+ * @throws Exception not part of this test case.
+ */
+ @Test(groups = { UNIT })
+ public void testGatherMultipleArtifactsOfMultipleVersionTargetOk() throws Exception {
+ DeploymentArtifactCollector handler = new DeploymentArtifactCollector(MULTIPLEVERSIONTARGET, VERSION2);
+
+ m_parser.parse(m_inputStream, handler);
+
+ List<XmlDeploymentArtifact>[] artifacts = handler.getArtifacts();
+ assert artifacts.length == 1 : "Expected two artifacts to be found!";
+ assert artifacts[0].size() == 2 : "Expected two artifacts to be found!";
+
+ XmlDeploymentArtifact artifact1 = artifacts[0].get(0);
+ assert new URL("file:///bundle4.1").equals(artifact1.getUrl()) : "Expected 'file:///bundle4.1' URL to be found!";
+ assert artifact1.getDirective().size() == 2 : "Expected two directives to be found!";
+ assert "bundle4.1".equals(artifact1.getDirective().get(KEY_SYMBOLICNAME)) : "Expected correct symbolic name to be found!";
+ assert "4.1.0".equals(artifact1.getDirective().get(KEY_VERSION)) : "Expected correct bundle version to be found!";
+
+ XmlDeploymentArtifact artifact2 = artifacts[0].get(1);
+ assert new URL("file:///bundle5").equals(artifact2.getUrl()) : "Expected 'file:///bundle5' URL to be found!";
+ assert artifact2.getDirective().size() == 2 : "Expected two directives to be found!";
+ assert "bundle5".equals(artifact2.getDirective().get(KEY_SYMBOLICNAME)) : "Expected correct symbolic name to be found!";
+ assert "5.0.0".equals(artifact2.getDirective().get(KEY_VERSION)) : "Expected correct bundle version to be found!";
+ }
+
+ /**
+ * Tests that single artifact of a deployment package with multiple versions can be parsed & found.
+ *
+ * @throws Exception not part of this test case.
+ */
+ @Test(groups = { UNIT })
+ public void testGatherSingleArtifactsOfMultipleVersionTargetOk() throws Exception {
+ DeploymentArtifactCollector handler = new DeploymentArtifactCollector(MULTIPLEVERSIONTARGET, VERSION3);
+
+ m_parser.parse(m_inputStream, handler);
+
+ List<XmlDeploymentArtifact>[] artifacts = handler.getArtifacts();
+ assert artifacts.length == 1 : "Expected a single artifact to be found!";
+ assert artifacts[0].size() == 1 : "Expected a single artifact to be found!";
+
+ XmlDeploymentArtifact artifact1 = artifacts[0].get(0);
+ assert new URL("file:///bundle4").equals(artifact1.getUrl()) : "Expected 'file:///bundle4' URL to be found!";
+ assert artifact1.getDirective().size() == 2 : "Expected two directives to be found!";
+ assert "bundle4".equals(artifact1.getDirective().get(KEY_SYMBOLICNAME)) : "Expected correct symbolic name to be found!";
+ assert "4.0.0".equals(artifact1.getDirective().get(KEY_VERSION)) : "Expected correct bundle version to be found!";
+ }
+
+ /**
+ * Tests that non existing artifacts of a deployment package with multiple versions can be parsed.
+ *
+ * @throws Exception not part of this test case.
+ */
+ @Test(groups = { UNIT })
+ public void testGatherNonExistingArtifactsOfMultipleVersionTargetOk() throws Exception {
+ DeploymentArtifactCollector handler = new DeploymentArtifactCollector(EMPTYVERSIONTARGET, VERSION2);
+
+ m_parser.parse(m_inputStream, handler);
+
+ List<XmlDeploymentArtifact>[] artifacts = handler.getArtifacts();
+ assert artifacts.length == 1 : "Expected a single artifact to be found!";
+ assert artifacts[0].isEmpty() : "Expected no deployment artifacts to be found!";
+ }
+
+ /**
+ * Tests that requesting the artifacts of a deployment package with an invalid version can be done.
+ *
+ * @throws Exception not part of this test case.
+ */
+ @Test(groups = { UNIT })
+ public void testGatherArtifactsOfMultipleVersionTargetWithInvalidVersionOk() throws Exception {
+ DeploymentArtifactCollector handler = new DeploymentArtifactCollector(EMPTYVERSIONTARGET, VERSION3);
+
+ m_parser.parse(m_inputStream, handler);
+
+ try {
+ handler.getArtifacts();
+
+ assert false : "Expected no deployment artifacts to be found!";
+ }
+ catch (IllegalArgumentException e) {
+ // Ok; expected...
+ }
+ }
+
+ /**
+ * @return a valid repository XML; never <code>null</code>.
+ */
+ private String generateValidTestXml() {
+ Document doc = null;
+ try {
+ DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+ doc = docBuilder.newDocument();
+ }
+ catch (ParserConfigurationException e) {
+ // Should not happen
+ e.printStackTrace();
+ }
+
+ // create the root element
+ Element root = doc.createElement("repository");
+ doc.appendChild(root);
+
+ // create the versions element
+ Element versions = doc.createElement("deploymentversions");
+ root.appendChild(versions);
+
+ // create deployment versions
+ versions.appendChild(generateDeploymentVersion(doc, TARGET, VERSION1, new String[] { "file:///bundle1",
+ KEY_SYMBOLICNAME, "bundle1", KEY_VERSION, VERSION1 }));
+
+ versions.appendChild(generateDeploymentVersion(doc, MULTIPLEVERSIONTARGET, VERSION1, new String[] {
+ "file:///bundle3", KEY_SYMBOLICNAME, "bundle3", KEY_VERSION, VERSION3 },
+ new String[] { "file:///bundle4", KEY_SYMBOLICNAME, "bundle4", KEY_VERSION,
+ VERSION4 }));
+ versions.appendChild(generateDeploymentVersion(doc, MULTIPLEVERSIONTARGET, VERSION2, new String[] {
+ "file:///bundle4.1", KEY_SYMBOLICNAME, "bundle4.1", KEY_VERSION, VERSION4_1 },
+ new String[] { "file:///bundle5", KEY_SYMBOLICNAME, "bundle5", KEY_VERSION,
+ VERSION5 }));
+ versions.appendChild(generateDeploymentVersion(doc, MULTIPLEVERSIONTARGET, VERSION3, new String[] {
+ "file:///bundle4", KEY_SYMBOLICNAME, "bundle4", KEY_VERSION, VERSION4 }));
+ versions.appendChild(generateDeploymentVersion(doc, MULTIPLEVERSIONTARGET, VERSION4, new String[] {
+ "file:///bundle3.2", KEY_SYMBOLICNAME, "bundle3.2", KEY_VERSION, VERSION3_2 },
+ new String[] { "file:///bundle4.2", KEY_SYMBOLICNAME, "bundle4.2", KEY_VERSION,
+ VERSION4_2 }));
+
+ // Add a valid deployment version (5.0.0) with no bundle urls (empty package)
+ versions.appendChild(generateDeploymentVersion(doc, EMPTYVERSIONTARGET, VERSION1, new String[] {
+ "file:///bundle1", KEY_SYMBOLICNAME, "bundle1", KEY_VERSION, VERSION1 }));
+ versions.appendChild(generateDeploymentVersion(doc, EMPTYVERSIONTARGET, VERSION2));
+
+ // transform the document to string
+ TransformerFactory tFactory = TransformerFactory.newInstance();
+ Transformer transformer = null;
+ StringWriter sw = null;
+ try {
+ transformer = tFactory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ DOMSource source = new DOMSource(doc);
+ sw = new StringWriter();
+ StreamResult result = new StreamResult(sw);
+ transformer.transform(source, result);
+ }
+ catch (TransformerConfigurationException e) {
+ // Should not happen
+ e.printStackTrace();
+ }
+ catch (TransformerException e) {
+ // Should not happen
+ e.printStackTrace();
+ }
+
+ return sw.toString();
+ }
+
+ /**
+ * Helper method to create the description of a deploymentpacakge with given data.
+ *
+ * @param doc The document to add the version to.
+ * @param targetText The targetId in the deploymentversion.
+ * @param versionText The version in the deploymentversion.
+ * @param data An array of data for the deployment artifact. [0] is the url, and each following item is
+ * first a directive key, and a directive value. For example,<br>
+ * <code>new String[] { "http://mybundle", "somedirective", "somevalue" }</code>
+ * @return
+ */
+ private Node generateDeploymentVersion(Document doc, String targetText, String versionText, String[]... data) {
+ Element deploymentversion = doc.createElement(DEPLOYMENTVERSION_TAG);
+ Element attr = doc.createElement(ATTRIBUTES_TAG);
+ deploymentversion.appendChild(attr);
+
+ // Create and add targetId Tag
+ Element elem = null;
+ elem = doc.createElement(TARGETID_TAG);
+ elem.setTextContent(targetText);
+ attr.appendChild(elem);
+
+ // Create and add versionTag
+ elem = doc.createElement(VERSION_TAG);
+ elem.setTextContent(versionText);
+ attr.appendChild(elem);
+
+ // Create and add empty tagsTag to deploymentversion
+ elem = doc.createElement(TAGS_TAG);
+ deploymentversion.appendChild(elem);
+
+ // create and add bundlesTag
+ elem = doc.createElement(ARTIFACTS_TAG);
+ for (String[] s : data) {
+ Element artifact = doc.createElement(ARTIFACT_TAG);
+ Element url = doc.createElement(URL_TAG);
+ url.setTextContent(s[0]);
+ artifact.appendChild(url);
+ Element directives = doc.createElement(DIRECTIVES_TAG);
+ for (int i = 1; i < s.length; i += 2) {
+ Element directive = doc.createElement(s[i]);
+ directive.setTextContent(s[i + 1]);
+ directives.appendChild(directive);
+ }
+ artifact.appendChild(directives);
+ elem.appendChild(artifact);
+ }
+
+ deploymentversion.appendChild(elem);
+
+ return deploymentversion;
+ }
+
+}
Added: ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/CacheTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/CacheTest.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/CacheTest.java (added)
+++ ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/CacheTest.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.provider.repositorybased;
+
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class CacheTest {
+ @Test(groups = { UNIT })
+ public void testFillCacheToLimitAndCheckIfEverythingFits() {
+ LRUMap<String, String> map = new LRUMap<String, String>();
+ for (int i = 0; i < 1024; i++) {
+ String key = "" + i;
+ map.put(key, key);
+ }
+ for (int i = 0; i < 1024; i++) {
+ String key = "" + i;
+ Assert.assertEquals(map.get(key), key);
+ }
+ }
+
+ @Test(groups = { UNIT })
+ public void testOverflowCacheAndValidateOldestElementDisappears() {
+ LRUMap<String, String> map = new LRUMap<String, String>();
+ // add one too many
+ for (int i = 0; i < 1025; i++) {
+ String key = "" + i;
+ map.put(key, key);
+ }
+ // retrieve in same order (first one should be gone)
+ for (int i = 0; i < 1025; i++) {
+ String key = "" + i;
+ if (i == 0) {
+ Assert.assertNull(map.get(key));
+ }
+ else {
+ Assert.assertEquals(map.get(key), key);
+ }
+ }
+ // access the second one
+ map.get("1");
+ // add another one
+ String key = "1025";
+ map.put(key, key);
+ // make sure the third is gone now
+ Assert.assertNull(map.get("2"));
+ }
+}
Added: ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/MockDeploymentRepository.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/MockDeploymentRepository.java?rev=1464402&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/MockDeploymentRepository.java (added)
+++ ace/trunk/org.apache.ace.deployment/test/org/apache/ace/deployment/provider/repositorybased/MockDeploymentRepository.java Thu Apr 4 09:43:34 2013
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.deployment.provider.repositorybased;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.ace.range.SortedRangeSet;
+import org.apache.ace.repository.Repository;
+
+public class MockDeploymentRepository implements Repository {
+
+ private String m_range;
+ private String m_xmlRepository;
+
+ public MockDeploymentRepository(String range, String xmlRepository) {
+ m_range = range;
+ m_xmlRepository = xmlRepository;
+ }
+
+ /* (non-Javadoc)
+ * Magic number version 1, generates an IOException, else return
+ * @see org.apache.ace.repository.Repository#checkout(long)
+ */
+ public InputStream checkout(long version) throws IOException, IllegalArgumentException {
+ if (version == 1) {
+ //throw an IOException!
+ throw new IOException("Checkout exception.");
+ }
+ else {
+ return new ByteArrayInputStream(m_xmlRepository.getBytes());
+ }
+ }
+
+ public boolean commit(InputStream data, long fromVersion) throws IOException, IllegalArgumentException {
+ // Not used in test
+ return false;
+ }
+
+ public SortedRangeSet getRange() throws IOException {
+ return new SortedRangeSet(m_range);
+ }
+}