/*
* 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.openejb.tck.cdi.tomee.embedded;
import org.apache.commons.io.FileUtils;
import org.apache.openejb.config.ValidationException;
import org.apache.openejb.tck.OpenEJBTCKRuntimeException;
import org.apache.tomee.embedded.Container;
import org.jboss.testharness.api.DeploymentException;
import org.jboss.testharness.spi.Containers;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.Flushable;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @version $Rev$ $Date$
*/
public class ContainersImpl implements Containers {
private static int count = 0;
private static final String tmpDir = System.getProperty("java.io.tmpdir");
private Exception exception;
private final Container container;
private static final Map<String, File> FILES = new ConcurrentHashMap<String, File>();
public ContainersImpl() {
System.out.println("Initialized ContainersImpl " + (++count));
container = new Container();
System.setProperty("tomee.valves", ResetStaticValve.class.getName());
}
@Override
public boolean deploy(InputStream archive, String name) throws IOException {
exception = null;
System.out.println("Deploying " + archive + " with name " + name);
File application = getFile(name);
System.out.println(application);
FILES.put(name, application.getParentFile());
writeToFile(application, archive);
try {
container.deploy(name, application);
} catch (Exception ex) {
Exception e = ex;
if (e.getCause() instanceof ValidationException) {
e = (Exception) e.getCause();
}
if (name.contains(".broken.")) {
// Tests that contain the name '.broken.' are expected to fail deployment
// This is how the TCK verifies the container is doing the required error checking
exception = (DeploymentException) new DeploymentException("deploy failed").initCause(e);
} else {
// This on the other hand is not good ....
System.out.println("FIX Deployment of " + name);
e.printStackTrace();
exception = e;
}
return false;
}
return true;
}
private void writeToFile(File file, InputStream archive) {
try {
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = archive.read(buffer)) > -1) {
fos.write(buffer, 0, bytesRead);
}
Util.close(fos);
} catch (Exception e) {
throw new OpenEJBTCKRuntimeException(e);
}
}
private File getFile(String name) {
final File dir = new File(tmpDir, Math.random() + "");
dir.mkdirs();
dir.deleteOnExit();
return new File(dir, name);
}
@Override
public DeploymentException getDeploymentException() {
try {
return (DeploymentException) exception;
} catch (Exception e) {
System.out.println("BADCAST");
return new DeploymentException("", exception);
}
}
@Override
public void undeploy(String name) throws IOException {
System.out.println("Undeploying " + name);
try {
container.undeploy(name);
} catch (Exception e) {
e.printStackTrace();
throw new OpenEJBTCKRuntimeException(e);
}
File file = FILES.remove(name);
System.out.println("deleting " + file.getAbsolutePath());
FileUtils.deleteDirectory(file);
}
@Override
public void setup() throws IOException {
try {
container.start();
} catch (Exception e) {
throw new IOException(e);
}
}
@Override
public void cleanup() throws IOException {
try {
container.stop();
} catch (Exception e) {
throw new IOException(e);
}
for (File f : FILES.values()) {
FileUtils.deleteDirectory(f);
}
FILES.clear();
}
private static final class Util {
static void close(Closeable closeable) throws IOException {
if (closeable == null)
return;
try {
if (closeable instanceof Flushable) {
((Flushable) closeable).flush();
}
} catch (IOException e) {
// no-op
}
try {
closeable.close();
} catch (IOException e) {
// no-op
}
}
}
}