Skip to content

Commit

Permalink
Addressing AS7-6731 [bz920113]
Browse files Browse the repository at this point in the history
Module dependency on xalan now uses services=import
Adding javadoc to various bits of the code
Fixes an issue where an error during sanitation causes
0 length files to be stored in the archive.
  • Loading branch information
jhjaggars authored and bstansberry committed Mar 14, 2013
1 parent c589306 commit a10bd88
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<module name="javax.api"/>
<module name="org.apache.commons.cli"/>
<module name="org.apache.commons.io"/>
<module name="org.apache.xalan"/>
<module name="org.apache.xalan" services="import"/>
<module name="org.jboss.staxmapper"/>
<module name="org.jboss.as.controller"/>
<module name="org.jboss.as.network"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,72 @@

import org.jboss.dmr.ModelNode;

/**
* <p>
* Command to call the AS 7 management system and store the output in a file.
*</p>
* <p>
* This class' methods are meant to be chained together to describe a management call. For example:
*</p>
* <pre>
* new CallAS7("my_file").resource("foo", "bar").operation("read-resource")
*</pre>
*
* <p>
* will return a configured CallAS7 instance that will, when executed call {@code read-resource}
* on the {@code /foo=bar/} resource, and store the output in a file called {@code my_file.json}.
* </p>
*/
public class CallAS7 extends JdrCommand {

private String operation = "read-resource";
private LinkedList<String> resource = new LinkedList<String>();
private Map<String, String> parameters = new HashMap<String, String>();
private String name;

/**
* constructs an instance and sets the resulting file name
*
* @param name of the file to write results to
*/
public CallAS7(String name) {
this.name = name + ".json";
}

/**
* sets the operation to call
*
* @param operation to call, defaults to {@code read-resource}
* @return this
*/
public CallAS7 operation(String operation) {
this.operation = operation;
return this;
}

/**
* adds a key/value parameter pair to the call
*
* @param key
* @param val
* @return this
*/
public CallAS7 param(String key, String val) {
this.parameters.put(key, val);
return this;
}

/**
* appends resource parts to the resource to call
* <p></p>
* If you want to call /foo=bar/baz=boo/, do this:
* <pre>
* .resource("foo", "bar", "baz", "boo")
* </pre>
*
* @param parts to call
* @return this
*/
public CallAS7 resource(String... parts) {
for(String part : parts ) {
this.resource.add(part);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,23 @@
*/
package org.jboss.as.jdr.commands;

/**
* Abstract class that should be subclassed by JDR Commands.
*
* The purpose of this class is to standardize the method by which the
* JdrEnvironment is shared with Commands.
*/
public abstract class JdrCommand {
JdrEnvironment env;

public void setEnvironment(JdrEnvironment env) {
this.env = env;
}

/**
* executes the command
* {@link org.jboss.as.jdr.plugins.JdrPlugin} implementations do not need to call this method.
* @throws Exception
*/
public abstract void execute() throws Exception;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.jdr.util.JdrZipFile;

/**
* Value object of globally useful data.
*
* This object contains information that is designed to be used by Commands. It isn't thread safe.
* Most commands will need to interact with the {@link JdrZipFile} zip member.
*/
public class JdrEnvironment {
private String jbossHome = System.getenv("JBOSS_HOME");
private String username;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

import java.io.InputStream;

/**
* Provides a default implementation of {@link Sanitizer} that uses default
* filtering. Sanitizers should subclass this unless they wish to use complex
* accepts filtering.
*/
abstract class AbstractSanitizer implements Sanitizer {

protected VirtualFileFilter filter = Filters.TRUE;
Expand All @@ -14,6 +19,12 @@ abstract class AbstractSanitizer implements Sanitizer {
public abstract InputStream sanitize(InputStream in) throws Exception;


/**
* returns whether or not a VirtualFile should be processed by this sanitizer.
*
* @param resource {@link VirtualFile} resource to test
* @return
*/
@Override
public boolean accepts(VirtualFile resource) {
return filter.accepts(resource);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@

import static org.jboss.as.jdr.JdrLogger.ROOT_LOGGER;

/**
* Abstracts the zipfile used for packaging the JDR Report.
*/
public class JdrZipFile {

ZipOutputStream zos;
Expand Down Expand Up @@ -64,10 +67,21 @@ public JdrZipFile(JdrEnvironment env) throws Exception {
zos = new ZipOutputStream(new FileOutputStream(this.name));
}

/**
* @return the full pathname to the zipfile on disk
*/
public String name() {
return this.name;
}

/**
* Adds the contents of the {@link InputStream} to the path in the zip.
*
* This method allows for absolute control of the destination of the content to be stored.
* It is not common to use this method.
* @param is content to write
* @param path destination to write to in the zip file
*/
public void add(InputStream is, String path) {
byte [] buffer = new byte[1024];

Expand Down Expand Up @@ -97,16 +111,44 @@ public void add(InputStream is, String path) {
}
}

/**
* Adds the content of the {@link InputStream} to the zip in a location that mirrors where {@link VirtualFile file} is located.
*
* For example if {@code file} is at {@code /tmp/foo/bar} and {@code $JBOSS_HOME} is {@code tmp} then the destination will be {@code JBOSSHOME/foo/bar}
*
* @param file {@link VirtualFile} where metadata is read from
* @param is content to write to the zip file
* @throws Exception
*/
public void add(VirtualFile file, InputStream is) throws Exception {
String name = "JBOSS_HOME" + file.getPathName().substring(this.jbossHome.length());
this.add(is, name);
}

/**
* Adds content to the zipfile at path
*
* path is prepended with the directory reserved for generated text files in JDR
*
* @param content
* @param path
* @throws Exception
*/
public void add(String content, String path) throws Exception {
String name = "sos_strings/as7/" + path;
this.add(new ByteArrayInputStream(content.getBytes()), name);
}


/**
* Adds content to the zipfile in a file named logName
*
* path is prepended with the directory reserved for JDR log files
*
* @param content
* @param logName
* @throws Exception
*/
public void addLog(String content, String logName) throws Exception {
String name = "sos_logs/" + logName;
this.add(new ByteArrayInputStream(content.getBytes()), name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* {@link Sanitizer} subclass that replaces all instance of {@code pattern} with
* the {@code replacement} text.
*/
public class PatternSanitizer extends AbstractSanitizer {

private final Pattern pattern;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,32 @@

import org.jboss.as.jdr.vfs.Filters;

/**
* Provides the most commonly used sanitizers with their most common configurations.
*/
public class Sanitizers {

/**
* creates and returns a {@link Sanitizer} instance that only operates on
* files that end with a {@code .properties} suffix.
*
* @param pattern {@link WildcardPattern} compatible pattern to search for
* @param replacement text content to replace matches with
* @return {@link Sanitizer} that only operates on files with names ending with {@code .properties}.
* @throws Exception
*/
public static Sanitizer pattern(String pattern, String replacement) throws Exception {
return new PatternSanitizer(pattern, replacement, Filters.suffix(".properties"));
}

/**
* creates and returns a {@link Sanitizer} instance that only operates on
* files that end with a {@code .xml} suffix.
*
* @param xpath to search for and nullify
* @return a {@link Sanitizer} instance that only operates on files that end with a {@code .xml} suffix.
* @throws Exception
*/
public static Sanitizer xml(String xpath) throws Exception {
return new XMLSanitizer(xpath, Filters.suffix(".xml"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/
package org.jboss.as.jdr.util;

import org.apache.commons.io.IOUtils;
import org.jboss.vfs.VirtualFileFilter;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
Expand All @@ -39,6 +40,12 @@
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import static org.jboss.as.jdr.JdrLogger.ROOT_LOGGER;

/**
* {@link Sanitizer} subclass that removes the contents of the matched xpath expression
* in {@code pattern}.
*/
public class XMLSanitizer extends AbstractSanitizer {

private XPathExpression expression;
Expand All @@ -61,8 +68,10 @@ public XMLSanitizer(String pattern, VirtualFileFilter filter) throws Exception {
}

public InputStream sanitize(InputStream in) throws Exception {
byte [] content = IOUtils.toByteArray(in);
try {
Document doc = builder.parse(in);
// storing the entire file in memory in case we need to bail.
Document doc = builder.parse(new ByteArrayInputStream(content));
Object result = expression.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
Expand All @@ -74,7 +83,8 @@ public InputStream sanitize(InputStream in) throws Exception {
transformer.transform(source, outStream);
return new ByteArrayInputStream(output.toByteArray());
} catch (Exception e) {
return in;
ROOT_LOGGER.debug("Error while sanitizing an xml document", e);
return new ByteArrayInputStream(content);
}
}
}

0 comments on commit a10bd88

Please sign in to comment.