Author: orudyy
Date: Mon Jun 29 15:28:26 2015
New Revision: 1688251
URL: http://svn.apache.org/r1688251
Log:
QPID-6616: Rename TypedContent into Content
introduce ContentHeader annotation to mark methods returning values
for content headers
move responsibility to write content to the implementations
set HTTP headers in REST layer from the Content implementation
methods annotated with ContentHeader
(work by Lorenz Quack and Alex Rudyy)
Added:
qpid/java/trunk/broker-codegen/src/main/java/org/apache/qpid/server/model/validation/ContentHeaderAnnotationValidator.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Content.java
- copied, changed from r1688178,
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TypedContent.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ContentHeader.java
- copied, changed from r1688178,
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TypedContent.java
Removed:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TypedContent.java
Modified:
qpid/java/trunk/broker-codegen/src/main/resources/META-INF/services/javax.annotation.processing.Processor
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLogger.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLogger.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLoggerImpl.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/logback/RolloverWatcherTest.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
Added:
qpid/java/trunk/broker-codegen/src/main/java/org/apache/qpid/server/model/validation/ContentHeaderAnnotationValidator.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-codegen/src/main/java/org/apache/qpid/server/model/validation/ContentHeaderAnnotationValidator.java?rev=1688251&view=auto
==============================================================================
---
qpid/java/trunk/broker-codegen/src/main/java/org/apache/qpid/server/model/validation/ContentHeaderAnnotationValidator.java
(added)
+++
qpid/java/trunk/broker-codegen/src/main/java/org/apache/qpid/server/model/validation/ContentHeaderAnnotationValidator.java
Mon Jun 29 15:28:26 2015
@@ -0,0 +1,172 @@
+/*
+ * 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.qpid.server.model.validation;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+@SupportedAnnotationTypes(ContentHeaderAnnotationValidator.CONTENT_HEADER_CLASS_NAME)
+public class ContentHeaderAnnotationValidator extends AbstractProcessor
+{
+ public static final String CONTENT_HEADER_CLASS_NAME =
"org.apache.qpid.server.model.ContentHeader";
+ public static final String CONTENT_CLASS_NAME =
"org.apache.qpid.server.model.Content";
+ private static final Set<TypeKind> VALID_PRIMITIVE_TYPES = new
HashSet<>(Arrays.asList(
+ TypeKind.BOOLEAN,
+ TypeKind.BYTE,
+ TypeKind.CHAR,
+ TypeKind.DOUBLE,
+ TypeKind.FLOAT,
+ TypeKind.INT,
+ TypeKind.LONG,
+ TypeKind.SHORT));
+
+ @Override
+ public SourceVersion getSupportedSourceVersion()
+ {
+ return SourceVersion.latest();
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv)
+ {
+ Elements elementUtils = processingEnv.getElementUtils();
+ TypeElement annotationElement =
elementUtils.getTypeElement(CONTENT_HEADER_CLASS_NAME);
+
+ for (Element e : roundEnv.getElementsAnnotatedWith(annotationElement))
+ {
+ ExecutableElement methodElement = (ExecutableElement) e;
+
+ checkClassExtendsContent(annotationElement, methodElement);
+ checkMethodHasNoArgs(annotationElement, methodElement);
+ checkMethodReturnsString(annotationElement, methodElement);
+ }
+
+ return false;
+ }
+
+ private void checkMethodReturnsString(TypeElement annotationElement,
ExecutableElement methodElement)
+ {
+ final TypeMirror returnType = methodElement.getReturnType();
+
+ if (!isValidType(returnType))
+ {
+ processingEnv.getMessager()
+ .printMessage(Diagnostic.Kind.ERROR,
+ "@"
+ + annotationElement.getSimpleName()
+ + " can only be applied to methods with
primitive, boxed primitive, enum, or String type return type but annotated
Method "
+ + methodElement.getSimpleName() + "
returns "
+ + returnType.toString(),
+ methodElement
+ );
+ }
+ }
+
+ private boolean isValidType(TypeMirror type)
+ {
+ Types typeUtils = processingEnv.getTypeUtils();
+ Elements elementUtils = processingEnv.getElementUtils();
+ Element typeElement = typeUtils.asElement(type);
+
+ if (VALID_PRIMITIVE_TYPES.contains(type.getKind()))
+ {
+ return true;
+ }
+ for (TypeKind primitive : VALID_PRIMITIVE_TYPES)
+ {
+ if (typeUtils.isSameType(type,
typeUtils.boxedClass(typeUtils.getPrimitiveType(primitive)).asType()))
+ {
+ return true;
+ }
+ }
+ if (typeElement != null && typeElement.getKind() == ElementKind.ENUM)
+ {
+ return true;
+ }
+ if (typeUtils.isSameType(type,
elementUtils.getTypeElement("java.lang.String").asType()))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ private void checkMethodHasNoArgs(TypeElement annotationElement,
ExecutableElement methodElement)
+ {
+ if (!methodElement.getParameters().isEmpty())
+ {
+ processingEnv.getMessager()
+ .printMessage(Diagnostic.Kind.ERROR,
+ "@"
+ + annotationElement.getSimpleName()
+ + " can only be applied to methods without
arguments"
+ + " which does not apply to "
+ + methodElement.getSimpleName(),
+ methodElement);
+ }
+ }
+
+ private void checkClassExtendsContent(TypeElement annotationElement,
Element e)
+ {
+ Types typeUtils = processingEnv.getTypeUtils();
+ TypeMirror contentType = getErasure(CONTENT_CLASS_NAME);
+ TypeElement parent = (TypeElement) e.getEnclosingElement();
+
+ if (!typeUtils.isAssignable(typeUtils.erasure(parent.asType()),
contentType))
+ {
+ processingEnv.getMessager()
+ .printMessage(Diagnostic.Kind.ERROR,
+ "@"
+ + annotationElement.getSimpleName()
+ + " can only be applied to methods within
a class implementing "
+ + contentType.toString()
+ + " which does not apply to "
+ + parent.asType().toString(),
+ e);
+ }
+ }
+
+ private TypeMirror getErasure(final String className)
+ {
+ return getErasure(processingEnv, className);
+ }
+
+ private static TypeMirror getErasure(ProcessingEnvironment processingEnv,
final String className)
+ {
+ final Types typeUtils = processingEnv.getTypeUtils();
+ final Elements elementUtils = processingEnv.getElementUtils();
+ return
typeUtils.erasure(elementUtils.getTypeElement(className).asType());
+ }
+
+}
Modified:
qpid/java/trunk/broker-codegen/src/main/resources/META-INF/services/javax.annotation.processing.Processor
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-codegen/src/main/resources/META-INF/services/javax.annotation.processing.Processor?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-codegen/src/main/resources/META-INF/services/javax.annotation.processing.Processor
(original)
+++
qpid/java/trunk/broker-codegen/src/main/resources/META-INF/services/javax.annotation.processing.Processor
Mon Jun 29 15:28:26 2015
@@ -24,3 +24,4 @@ org.apache.qpid.server.model.validation.
org.apache.qpid.server.model.validation.AttributeFieldValidation
org.apache.qpid.server.model.validation.ManagedAnnotationValidator
org.apache.qpid.server.model.validation.OperationAnnotationValidator
+org.apache.qpid.server.model.validation.ContentHeaderAnnotationValidator
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLogger.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLogger.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLogger.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLogger.java
Mon Jun 29 15:28:26 2015
@@ -20,9 +20,6 @@
*/
package org.apache.qpid.server.logging;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.nio.file.Path;
import java.util.Collection;
import org.apache.qpid.server.model.BrokerLogger;
@@ -31,7 +28,7 @@ import org.apache.qpid.server.model.Mana
import org.apache.qpid.server.model.ManagedObject;
import org.apache.qpid.server.model.ManagedOperation;
import org.apache.qpid.server.model.Param;
-import org.apache.qpid.server.model.TypedContent;
+import org.apache.qpid.server.model.Content;
@ManagedObject( category = false, type = BrokerFileLogger.TYPE)
public interface BrokerFileLogger<X extends BrokerFileLogger<X>> extends
BrokerLogger<X>
@@ -63,5 +60,5 @@ public interface BrokerFileLogger<X exte
Collection<String> getRolledFiles();
@ManagedOperation(nonModifying = true)
- TypedContent getFile(@Param(name = "fileName") String fileName);
+ Content getFile(@Param(name = "fileName") String fileName);
}
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/BrokerFileLoggerImpl.java
Mon Jun 29 15:28:26 2015
@@ -20,20 +20,12 @@
*/
package org.apache.qpid.server.logging;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
import java.nio.file.Path;
-import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
-import javax.activation.MimetypesFileTypeMap;
-
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.Context;
@@ -41,10 +33,9 @@ import ch.qos.logback.core.Context;
import org.apache.qpid.server.logging.logback.RollingPolicyDecorator;
import org.apache.qpid.server.logging.logback.RolloverWatcher;
import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.DerivedAttribute;
import org.apache.qpid.server.model.ManagedAttributeField;
import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
-import org.apache.qpid.server.model.TypedContent;
+import org.apache.qpid.server.model.Content;
import org.apache.qpid.server.util.DaemonThreadFactory;
public class BrokerFileLoggerImpl extends
AbstractBrokerLogger<BrokerFileLoggerImpl> implements
BrokerFileLogger<BrokerFileLoggerImpl>, FileLoggerSettings
@@ -125,7 +116,7 @@ public class BrokerFileLoggerImpl extend
}
@Override
- public TypedContent getFile(final String fileName)
+ public Content getFile(final String fileName)
{
return _rolloverWatcher.getTypedContent(fileName,
_fileName.equals(fileName));
}
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLogger.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLogger.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLogger.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLogger.java
Mon Jun 29 15:28:26 2015
@@ -21,7 +21,6 @@
package org.apache.qpid.server.logging;
-import java.nio.file.Path;
import java.util.Collection;
import org.apache.qpid.server.model.DerivedAttribute;
@@ -29,7 +28,7 @@ import org.apache.qpid.server.model.Mana
import org.apache.qpid.server.model.ManagedObject;
import org.apache.qpid.server.model.ManagedOperation;
import org.apache.qpid.server.model.Param;
-import org.apache.qpid.server.model.TypedContent;
+import org.apache.qpid.server.model.Content;
import org.apache.qpid.server.model.VirtualHostLogger;
@ManagedObject( category = false, type = VirtualHostFileLogger.TYPE)
@@ -63,5 +62,5 @@ public interface VirtualHostFileLogger<X
Collection<String> getRolledFiles();
@ManagedOperation(nonModifying = true)
- TypedContent getFile(@Param(name = "fileName") String fileName);
+ Content getFile(@Param(name = "fileName") String fileName);
}
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLoggerImpl.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLoggerImpl.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLoggerImpl.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/VirtualHostFileLoggerImpl.java
Mon Jun 29 15:28:26 2015
@@ -34,7 +34,7 @@ import org.apache.qpid.server.logging.lo
import org.apache.qpid.server.logging.logback.RolloverWatcher;
import org.apache.qpid.server.model.ManagedAttributeField;
import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
-import org.apache.qpid.server.model.TypedContent;
+import org.apache.qpid.server.model.Content;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.util.DaemonThreadFactory;
@@ -119,7 +119,7 @@ public class VirtualHostFileLoggerImpl e
}
@Override
- public TypedContent getFile(final String fileName)
+ public Content getFile(final String fileName)
{
return _rolloverWatcher.getTypedContent(fileName,
_fileName.equals(fileName));
}
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/logging/logback/PathTypedContent.java
Mon Jun 29 15:28:26 2015
@@ -20,45 +20,58 @@
*/
package org.apache.qpid.server.logging.logback;
-import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
import java.nio.file.Path;
-import org.apache.qpid.server.model.TypedContent;
+import org.apache.qpid.server.model.ContentHeader;
+import org.apache.qpid.server.model.Content;
-public class PathTypedContent implements TypedContent
+public class PathTypedContent implements Content
{
private final Path _path;
private final String _contentType;
+ private final String _disposition;
+ private final long _contentSize;
- public PathTypedContent(Path path, String contentType)
+ public PathTypedContent(Path path, String contentType)
{
_path = path;
_contentType = contentType;
+ _disposition = _path == null ? "attachment" : "attachment;
filename=\"" + _path.getFileName().toString() + "\"";
+ _contentSize = _path == null ? 0 : _path.toFile().length();
}
- @Override
+ @ContentHeader("Content-Type")
public String getContentType()
{
return _contentType;
}
- @Override
- public InputStream openInputStream() throws IOException
+ @ContentHeader("Content-Length")
+ public long getContentLength()
{
- return _path == null ? null : new FileInputStream(_path.toFile());
+ return _contentSize;
}
- @Override
- public long getSize()
+ @ContentHeader("Content-Disposition")
+ public String getContentDisposition()
{
- return _path == null ? 0 : _path.toFile().length();
+ return _disposition;
}
@Override
- public String getFileName()
+ public void write(OutputStream outputStream) throws IOException
{
- return _path == null ? null : _path.getFileName().toString();
+ if (_path != null && _path.toFile().exists())
+ {
+ Files.copy(_path, outputStream);
+ }
+ else
+ {
+ throw new FileNotFoundException();
+ }
}
}
Copied:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Content.java
(from r1688178,
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TypedContent.java)
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Content.java?p2=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Content.java&p1=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TypedContent.java&r1=1688178&r2=1688251&rev=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TypedContent.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Content.java
Mon Jun 29 15:28:26 2015
@@ -21,16 +21,10 @@
package org.apache.qpid.server.model;
import java.io.IOException;
-import java.io.InputStream;
+import java.io.OutputStream;
@ManagedAttributeValueType
-public interface TypedContent
+public interface Content
{
- String getContentType();
-
- InputStream openInputStream() throws IOException;
-
- long getSize();
-
- String getFileName();
+ void write(OutputStream outputStream) throws IOException;
}
Copied:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ContentHeader.java
(from r1688178,
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TypedContent.java)
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ContentHeader.java?p2=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ContentHeader.java&p1=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TypedContent.java&r1=1688178&r2=1688251&rev=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/TypedContent.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ContentHeader.java
Mon Jun 29 15:28:26 2015
@@ -20,17 +20,14 @@
*/
package org.apache.qpid.server.model;
-import java.io.IOException;
-import java.io.InputStream;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
-@ManagedAttributeValueType
-public interface TypedContent
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface ContentHeader
{
- String getContentType();
-
- InputStream openInputStream() throws IOException;
-
- long getSize();
-
- String getFileName();
+ String value();
}
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
Mon Jun 29 15:28:26 2015
@@ -248,6 +248,6 @@ public interface Queue<X extends Queue<X
long clearQueue();
@ManagedOperation
- TypedContent getMessageContent(@Param(name = "messageId") long messageId);
+ Content getMessageContent(@Param(name = "messageId") long messageId);
}
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
Mon Jun 29 15:28:26 2015
@@ -19,7 +19,9 @@
package org.apache.qpid.server.queue;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.security.AccessControlException;
import java.security.AccessController;
@@ -47,6 +49,7 @@ import javax.security.auth.Subject;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import org.apache.qpid.server.model.ContentHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -83,7 +86,7 @@ import org.apache.qpid.server.model.Queu
import org.apache.qpid.server.model.QueueNotificationListener;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.StateTransition;
-import org.apache.qpid.server.model.TypedContent;
+import org.apache.qpid.server.model.Content;
import org.apache.qpid.server.plugin.MessageFilterFactory;
import org.apache.qpid.server.plugin.QpidServiceLoader;
import org.apache.qpid.server.protocol.AMQSessionModel;
@@ -2525,6 +2528,37 @@ public abstract class AbstractQueue<X ex
}
}
+ public static class MessageContent implements Content
+ {
+ private final byte[] _data;
+ private final String _mimeType;
+
+ public MessageContent(byte[] data, String mimeType )
+ {
+ _data = data;
+ _mimeType = mimeType;
+ }
+
+ @Override
+ public void write(OutputStream outputStream) throws IOException
+ {
+ outputStream.write(_data);
+ }
+
+ @ContentHeader("Content-Type")
+ public String getContentType()
+ {
+ return _mimeType;
+ }
+
+ @ContentHeader("Content-Length")
+ public long getSize()
+ {
+ return _data.length;
+ }
+
+ }
+
private final class QueueEntryListener implements
StateChangeListener<MessageInstance, QueueEntry.State>
{
@@ -3254,38 +3288,13 @@ public abstract class AbstractQueue<X ex
}
@Override
- public TypedContent getMessageContent(final long messageId)
+ public Content getMessageContent(final long messageId)
{
final MessageFinder messageFinder = new MessageFinder(messageId);
visit(messageFinder);
if(messageFinder.isFound())
{
- return new TypedContent()
- {
- @Override
- public String getContentType()
- {
- return messageFinder.getMimeType();
- }
-
- @Override
- public InputStream openInputStream()
- {
- return new
ByteArrayInputStream(messageFinder.getContent());
- }
-
- @Override
- public long getSize()
- {
- return messageFinder.getContent().length;
- }
-
- @Override
- public String getFileName()
- {
- return null;
- }
- };
+ return new MessageContent(messageFinder.getContent(),
messageFinder.getMimeType());
}
else
{
Modified:
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/logback/RolloverWatcherTest.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/logback/RolloverWatcherTest.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/logback/RolloverWatcherTest.java
(original)
+++
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/logback/RolloverWatcherTest.java
Mon Jun 29 15:28:26 2015
@@ -23,13 +23,13 @@ package org.apache.qpid.server.logging.l
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashSet;
-import org.apache.qpid.server.model.TypedContent;
+import org.apache.qpid.server.model.Content;
import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.test.utils.TestFileUtils;
import org.apache.qpid.util.FileUtils;
@@ -72,11 +72,12 @@ public class RolloverWatcherTest extends
final File activeFile = new File(_baseFolder, "test.log");
TestFileUtils.saveTextContentInFile("test", activeFile);
- TypedContent content =
_rolloverWatcher.getTypedContent(activeFile.getAbsolutePath(), true);
+ PathTypedContent content =
_rolloverWatcher.getTypedContent(activeFile.getAbsolutePath(), true);
assertEquals("Unexpected content type", "text/plain",
content.getContentType());
- assertEquals("Unexpected data", "test",
readStream(content.openInputStream()));
- assertEquals("Unexpected size", 4, content.getSize());
+ assertEquals("Unexpected data", "test", readContent(content));
+ assertEquals("Unexpected size", 4, content.getContentLength());
+ assertEquals("Unexpected content disposition", "attachment;
filename=\"" + activeFile.getName().toString() + "\"",
content.getContentDisposition());
}
public void testGetTypedForNullFile() throws Exception
@@ -99,11 +100,12 @@ public class RolloverWatcherTest extends
TestFileUtils.saveTextContentInFile("test.gz", new File(_baseFolder,
"test1.gz"));
- TypedContent content = _rolloverWatcher.getTypedContent("test1.gz",
false);
+ PathTypedContent content =
_rolloverWatcher.getTypedContent("test1.gz", false);
assertEquals("Unexpected content type", "application/x-gzip",
content.getContentType());
- assertEquals("Unexpected data", "test.gz",
readStream(content.openInputStream()));
- assertEquals("Unexpected size", 7, content.getSize());
+ assertEquals("Unexpected data", "test.gz", readContent(content));
+ assertEquals("Unexpected size", 7, content.getContentLength());
+ assertEquals("Unexpected content disposition", "attachment;
filename=\"test1.gz\"", content.getContentDisposition());
}
public void testGetTypedContentForNonExistingRolledFile() throws Exception
@@ -112,11 +114,20 @@ public class RolloverWatcherTest extends
Path baseFolder = new File(getTestName()).toPath();
_rolloverWatcher.onRollover(baseFolder, files);
- TypedContent content = _rolloverWatcher.getTypedContent("test3.zip",
false);
+ PathTypedContent content =
_rolloverWatcher.getTypedContent("test3.zip", false);
assertEquals("Unexpected content type", "application/x-zip",
content.getContentType());
- assertNull("Unexpected content stream", content.openInputStream());
- assertEquals("Unexpected size", 0, content.getSize());
+ assertEquals("Unexpected content disposition", "attachment",
content.getContentDisposition());
+ assertEquals("Unexpected size", 0, content.getContentLength());
+ try
+ {
+ readContent(content);
+ fail("FileNotFoundException is expected");
+ }
+ catch(FileNotFoundException e)
+ {
+ //pass
+ }
}
public void testGetContentType() throws Exception
@@ -126,15 +137,10 @@ public class RolloverWatcherTest extends
assertEquals("Unexpected content type for zip file",
"application/x-zip", _rolloverWatcher.getContentType("test.zip"));
}
- private String readStream(InputStream contentStream) throws IOException
+ private String readContent(Content content) throws IOException
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int length;
- while ((length = contentStream.read(buffer)) > 0)
- {
- os.write(buffer, 0, length);
- }
+ content.write(os);
return new String(os.toByteArray());
}
}
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
Mon Jun 29 15:28:26 2015
@@ -22,14 +22,16 @@ package org.apache.qpid.server.managemen
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import javax.security.auth.Subject;
import javax.servlet.ServletConfig;
@@ -39,7 +41,8 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.qpid.server.model.TypedContent;
+import org.apache.qpid.server.model.Content;
+import org.apache.qpid.server.model.ContentHeader;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.slf4j.Logger;
@@ -332,44 +335,62 @@ public abstract class AbstractServlet ex
return null;
}
- protected void writeTypedContent(TypedContent typedContent,
HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void writeTypedContent(Content content, HttpServletRequest
request, HttpServletResponse response) throws IOException
{
- response.setContentType(typedContent.getContentType());
- response.setContentLength((int) typedContent.getSize());
- String fileName = typedContent.getFileName();
- if (fileName != null)
+ Map<ContentHeader, Method> contentHeaderGetters =
getContentHeaderMethods(content);
+ if (contentHeaderGetters != null)
{
- response.setHeader("Content-disposition", "attachment;
filename=\"" + fileName + "\"");
- }
+ for (Map.Entry<ContentHeader, Method> entry:
contentHeaderGetters.entrySet())
+ {
+ final String headerName = entry.getKey().value();
+ try
+ {
+ response.setHeader(headerName,
String.valueOf(entry.getValue().invoke(content)));
+ }
+ catch (Exception e)
+ {
+ LOGGER.warn("Unexpected exception whilst setting response
header " + headerName, e);
+ }
+ }
- try (InputStream contentStream = typedContent.openInputStream())
+ }
+ try(OutputStream os = getOutputStream(request, response))
{
- writeStreamContent(contentStream, request, response);
+ content.write(os);
+ response.setStatus(HttpServletResponse.SC_OK);
}
catch (FileNotFoundException e)
{
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
+ catch(IOException e)
+ {
+ LOGGER.warn("Unexpected exception processing request", e);
+ sendJsonErrorResponse(request, response,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+ }
}
- protected void writeStreamContent(InputStream contentStream,
HttpServletRequest request, HttpServletResponse response) throws IOException
+ private Map<ContentHeader, Method> getContentHeaderMethods(Content content)
{
- if (contentStream == null)
- {
- response.setStatus(HttpServletResponse.SC_NOT_FOUND);
- }
- else
+ Map<ContentHeader, Method> results = new HashMap<>();
+ Method[] methods = content.getClass().getMethods();
+ for (Method method: methods)
{
- response.setStatus(HttpServletResponse.SC_OK);
- try (OutputStream os = getOutputStream(request, response))
+ if (method.isAnnotationPresent(ContentHeader.class))
{
- byte[] buffer = new byte[8192];
- int length;
- while ((length = contentStream.read(buffer)) > 0)
+ final Class<?>[] parameterTypes = method.getParameterTypes();
+ if (parameterTypes.length >0)
+ {
+ LOGGER.warn("Parameters are found on method " +
method.getName()
+ + " annotated with ContentHeader annotation. No
parameter is allowed. Ignoring ContentHeader annotation.");
+ }
+ else
{
- os.write(buffer, 0, length);
+ results.put(method.getAnnotation(ContentHeader.class),
method);
}
}
}
+ return results;
}
+
}
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java
Mon Jun 29 15:28:26 2015
@@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletReq
import javax.servlet.http.HttpServletResponse;
import org.apache.qpid.server.model.Queue;
-import org.apache.qpid.server.model.TypedContent;
+import org.apache.qpid.server.model.Content;
import org.apache.qpid.server.model.VirtualHost;
public class MessageContentServlet extends AbstractServlet
@@ -49,7 +49,7 @@ public class MessageContentServlet exten
{
Queue queue = getQueueFromRequest(request);
String path[] = getPathInfoElements(request);
- TypedContent content =
queue.getMessageContent(Long.parseLong(path[2]));
+ Content content = queue.getMessageContent(Long.parseLong(path[2]));
if(content != null)
{
writeTypedContent(content, request, response);
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java?rev=1688251&r1=1688250&r2=1688251&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
Mon Jun 29 15:28:26 2015
@@ -16,9 +16,7 @@
*/
package org.apache.qpid.server.management.plugin.servlet.rest;
-import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
@@ -46,7 +44,7 @@ import org.apache.qpid.server.model.Abst
import org.apache.qpid.server.model.ConfiguredObjectOperation;
import org.apache.qpid.server.model.IllegalStateTransitionException;
import org.apache.qpid.server.model.IntegrityViolationException;
-import org.apache.qpid.server.model.TypedContent;
+import org.apache.qpid.server.model.Content;
import org.apache.qpid.server.util.ServerScopedRuntimeException;
import org.apache.qpid.server.virtualhost.ExchangeExistsException;
import org.apache.qpid.server.virtualhost.QueueExistsException;
@@ -607,10 +605,10 @@ public class RestServlet extends Abstrac
}
}
Object returnVal = operation.perform(subject, operationArguments);
- if(returnVal instanceof TypedContent)
+ if(returnVal instanceof Content)
{
- TypedContent typedContent = (TypedContent)returnVal;
- writeTypedContent(typedContent, request, response);
+ Content content = (Content)returnVal;
+ writeTypedContent(content, request, response);
}
else
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]