You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Sergey Beryozkin <sb...@gmail.com> on 2014/04/01 11:46:21 UTC
Re: git commit: [CXF-5661]add more JMX operations for ManagedEndpoint
mbean
Hi Freeman
IMHO it appears to be a rather 'intrusive' commit. I'm sure it will help
with the JMX improvements work somehow but here are some comments:
Here are some comments:
- should your bean annotation introspectors to do with JMX be moved to
rt/management, do they belong to the core ? All these Jackson deps just
hit the eye :-), nothing against Jackson here per se, just seems it is
not in the right place
- AbstractJAXRSFactoryBean update: I don't think we need to keep the
custom classes map within every created endpoint by default for the sake
of the optional JMX improvement: if you need it for the JMX work then
lets consider how this can be optionally done, example, add a service
endpoint listener and add the classes map from there, etc, so lets
remove those lines for now
Thanks, Sergey
On 01/04/14 07:43, ffang@apache.org wrote:
> Repository: cxf
> Updated Branches:
> refs/heads/master ee7ade9e4 -> 99eb3de3a
>
>
> [CXF-5661]add more JMX operations for ManagedEndpoint mbean
>
>
> Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
> Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/99eb3de3
> Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/99eb3de3
> Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/99eb3de3
>
> Branch: refs/heads/master
> Commit: 99eb3de3ab81776442f0fb1893f84c33a6b65242
> Parents: ee7ade9
> Author: Freeman Fang <fr...@gmail.com>
> Authored: Tue Apr 1 14:42:49 2014 +0800
> Committer: Freeman Fang <fr...@gmail.com>
> Committed: Tue Apr 1 14:42:49 2014 +0800
>
> ----------------------------------------------------------------------
> core/pom.xml | 33 +-
> .../BeanValidationAnnotationIntrospector.java | 110 ++++
> .../BeanValidationAnnotationModule.java | 40 ++
> .../cxf/endpoint/FourSpacePrettyPrinter.java | 78 +++
> ...IgnorePropertiesBackedByTransientFields.java | 241 +++++++++
> .../apache/cxf/endpoint/JsonSchemaLookup.java | 99 ++++
> .../apache/cxf/endpoint/ManagedEndpoint.java | 524 +++++++++++++++++++
> parent/pom.xml | 22 +-
> .../cxf/jaxrs/AbstractJAXRSFactoryBean.java | 8 +-
> rt/pom.xml | 1 -
> .../cxf/jaxrs/model/wadl/WadlGenerator.java | 24 +-
> .../cxf/jaxrs/swagger/SwaggerFeature.java | 18 +
> services/pom.xml | 1 -
> services/xkms/pom.xml | 1 -
> systests/jaxrs/pom.xml | 21 +
> .../systest/jaxrs/RestJsonSchemaJMXTest.java | 162 ++++++
> .../org/apache/cxf/systest/jaxrs/jmx-enable.xml | 16 +
> systests/jaxws/pom.xml | 21 +
> .../cxf/systest/jaxws/JsonSchemaJMXTest.java | 146 ++++++
> .../org/apache/cxf/systest/jaxws/jmx-enable.xml | 28 +
> 20 files changed, 1580 insertions(+), 14 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/pom.xml
> ----------------------------------------------------------------------
> diff --git a/core/pom.xml b/core/pom.xml
> index 199024f..546bcab 100644
> --- a/core/pom.xml
> +++ b/core/pom.xml
> @@ -187,7 +187,7 @@
> <dependency>
> <groupId>org.osgi</groupId>
> <artifactId>org.osgi.compendium</artifactId>
> - <scope>provided</scope>
> + <scope>compile</scope>
> </dependency>
> <dependency>
> <groupId>net.java.dev.msv</groupId>
> @@ -201,6 +201,37 @@
> <optional>true</optional>
> <scope>provided</scope>
> </dependency>
> +
> + <dependency>
> + <groupId>com.fasterxml.jackson.module</groupId>
> + <artifactId>jackson-module-jaxb-annotations</artifactId>
> + <optional>true</optional>
> + </dependency>
> +
> + <dependency>
> + <groupId>com.fasterxml.jackson.core</groupId>
> + <artifactId>jackson-databind</artifactId>
> + <optional>true</optional>
> + </dependency>
> +
> + <dependency>
> + <groupId>com.fasterxml.jackson.core</groupId>
> + <artifactId>jackson-annotations</artifactId>
> + <optional>true</optional>
> + </dependency>
> +
> + <dependency>
> + <groupId>com.fasterxml.jackson.core</groupId>
> + <artifactId>jackson-core</artifactId>
> + <optional>true</optional>
> + </dependency>
> +
> + <dependency>
> + <groupId>javax.validation</groupId>
> + <artifactId>validation-api</artifactId>
> + <optional>true</optional>
> + </dependency>
> +
> </dependencies>
> <build>
> <plugins>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationIntrospector.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationIntrospector.java b/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationIntrospector.java
> new file mode 100644
> index 0000000..936c039
> --- /dev/null
> +++ b/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationIntrospector.java
> @@ -0,0 +1,110 @@
> +/**
> + * 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.cxf.endpoint;
> +
> +
> +import java.beans.Introspector;
> +import java.lang.reflect.Field;
> +import java.lang.reflect.Member;
> +import java.lang.reflect.Modifier;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +import javax.validation.constraints.NotNull;
> +
> +import com.fasterxml.jackson.core.Version;
> +import com.fasterxml.jackson.databind.AnnotationIntrospector;
> +import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
> +import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
> +import com.fasterxml.jackson.databind.type.TypeFactory;
> +
> +import org.apache.cxf.common.logging.LogUtils;
> +
> +
> +public class BeanValidationAnnotationIntrospector extends AnnotationIntrospector {
> + private static final transient Logger LOG = LogUtils.getL7dLogger(BeanValidationAnnotationIntrospector.class);
> +
> + protected final TypeFactory typeFactory;
> +
> + public BeanValidationAnnotationIntrospector(TypeFactory typeFactory) {
> + this.typeFactory = (typeFactory == null) ? TypeFactory.defaultInstance() : typeFactory;
> + }
> +
> +
> + @Override
> + public Version version() {
> + return new Version(1, 1, 0, "", "cxf", "json-schema-mbean");
> + }
> +
> +
> + @Override
> + public boolean hasIgnoreMarker(AnnotatedMember m) {
> + Member member = m.getMember();
> + int modifiers = member.getModifiers();
> + if (Modifier.isTransient(modifiers)) {
> + if (LOG.isLoggable(Level.FINE)) {
> + LOG.fine("Ignoring transient member " + m);
> + }
> + return true;
> + } else if (m instanceof AnnotatedMethod) {
> + AnnotatedMethod method = (AnnotatedMethod) m;
> + String methodName = method.getName();
> + // lets see if there is a transient field of the same name as the getter
> + if (methodName.startsWith("get") && method.getParameterCount() == 0) {
> + String fieldName = Introspector.decapitalize(methodName.substring(3));
> + Class<?> declaringClass = method.getDeclaringClass();
> + Field field = findField(fieldName, declaringClass);
> + if (field != null) {
> + int fieldModifiers = field.getModifiers();
> + if (Modifier.isTransient(fieldModifiers)) {
> + LOG.fine("Ignoring member " + m + " due to transient field called " + fieldName);
> + return true;
> + }
> + }
> + }
> + }
> + return super.hasIgnoreMarker(m);
> +
> + }
> +
> + protected static Field findField(String fieldName, Class<?> declaringClass) {
> + try {
> + return declaringClass.getDeclaredField(fieldName);
> + } catch (NoSuchFieldException e) {
> + Class<?> superclass = declaringClass.getSuperclass();
> + if (superclass != null && superclass != declaringClass) {
> + return findField(fieldName, superclass);
> + } else {
> + return null;
> + }
> + }
> + }
> +
> + @Override
> + public Boolean hasRequiredMarker(AnnotatedMember m) {
> + NotNull annotation = m.getAnnotation(NotNull.class);
> + if (annotation == null) {
> + return null;
> + }
> + return Boolean.TRUE;
> + }
> +
> +
> +}
> +
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationModule.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationModule.java b/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationModule.java
> new file mode 100644
> index 0000000..f737178
> --- /dev/null
> +++ b/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationModule.java
> @@ -0,0 +1,40 @@
> +/**
> + * 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.cxf.endpoint;
> +
> +
> +
> +import com.fasterxml.jackson.databind.module.SimpleModule;
> +
> +
> +public class BeanValidationAnnotationModule extends SimpleModule {
> +
> + public BeanValidationAnnotationModule() {
> + super("bean-validation-annotations");
> + }
> +
> + @Override
> + public void setupModule(SetupContext context) {
> + BeanValidationAnnotationIntrospector introspector =
> + new BeanValidationAnnotationIntrospector(context.getTypeFactory());
> +
> + context.insertAnnotationIntrospector(introspector);
> + }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/FourSpacePrettyPrinter.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/FourSpacePrettyPrinter.java b/core/src/main/java/org/apache/cxf/endpoint/FourSpacePrettyPrinter.java
> new file mode 100644
> index 0000000..e8dc6d8
> --- /dev/null
> +++ b/core/src/main/java/org/apache/cxf/endpoint/FourSpacePrettyPrinter.java
> @@ -0,0 +1,78 @@
> +/**
> + * 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.cxf.endpoint;
> +
> +import java.io.IOException;
> +import java.util.Arrays;
> +
> +import com.fasterxml.jackson.core.JsonGenerationException;
> +import com.fasterxml.jackson.core.JsonGenerator;
> +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
> +
> +public class FourSpacePrettyPrinter extends DefaultPrettyPrinter {
> +
> + public FourSpacePrettyPrinter() {
> + _objectIndenter = Lf4SpacesIndenter.INSTANCE;
> + }
> +
> + public static class Lf4SpacesIndenter extends NopIndenter {
> + public static final Lf4SpacesIndenter INSTANCE = new Lf4SpacesIndenter();
> +
> + private static final String SYS_LF;
> +
> + private static int spacecount = 64;
> + private static char[] spaces = new char[spacecount];
> +
> + static {
> + String lf = null;
> + try {
> + lf = System.getProperty("line.separator");
> + } catch (Throwable t) {
> + //
> + }
> + SYS_LF = (lf == null) ? "\n" : lf;
> + }
> +
> +
> + static {
> + Arrays.fill(spaces, ' ');
> + }
> +
> +
> +
> + @Override
> + public boolean isInline() {
> + return false;
> + }
> +
> + @Override
> + public void writeIndentation(JsonGenerator jg, int level) throws IOException, JsonGenerationException {
> + jg.writeRaw(SYS_LF);
> + if (level > 0) { // should we err on negative values (as there's some flaw?)
> + level = level * 4; // 4 spaces per level
> + while (level > spacecount) { // should never happen but...
> + jg.writeRaw(spaces, 0, spacecount);
> + level -= spaces.length;
> + }
> + jg.writeRaw(spaces, 0, level);
> + }
> + }
> + }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/IgnorePropertiesBackedByTransientFields.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/IgnorePropertiesBackedByTransientFields.java b/core/src/main/java/org/apache/cxf/endpoint/IgnorePropertiesBackedByTransientFields.java
> new file mode 100644
> index 0000000..278cc37
> --- /dev/null
> +++ b/core/src/main/java/org/apache/cxf/endpoint/IgnorePropertiesBackedByTransientFields.java
> @@ -0,0 +1,241 @@
> +/**
> + * 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.cxf.endpoint;
> +
> +
> +
> +import java.beans.Introspector;
> +import java.lang.reflect.Field;
> +import java.lang.reflect.Member;
> +import java.lang.reflect.Method;
> +import java.lang.reflect.Modifier;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +import com.fasterxml.jackson.annotation.JsonAutoDetect;
> +import com.fasterxml.jackson.annotation.PropertyAccessor;
> +import com.fasterxml.jackson.databind.introspect.AnnotatedField;
> +import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
> +import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
> +import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
> +
> +import org.apache.cxf.common.logging.LogUtils;
> +
> +public class IgnorePropertiesBackedByTransientFields implements
> + VisibilityChecker<IgnorePropertiesBackedByTransientFields> {
> +
> + private static final transient Logger LOG = LogUtils.getL7dLogger(IgnorePropertiesBackedByTransientFields.class);
> + private final VisibilityChecker<?> defaultChecker;
> +
> + public IgnorePropertiesBackedByTransientFields(VisibilityChecker<?> defaultChecker) {
> + this.defaultChecker = defaultChecker;
> + }
> +
> + @Override
> + public boolean isGetterVisible(AnnotatedMethod method) {
> + boolean answer = defaultChecker.isGetterVisible(method);
> + if (answer) {
> + answer = isGetterMethodWithFieldVisible(method, getGetterFieldName(
> + method.getName()), method.getDeclaringClass())
> + && isGetterMethodRetItselfVisible(method.getMember(), method.getDeclaringClass());
> + }
> + return answer;
> + }
> +
> + @Override
> + public boolean isGetterVisible(Method method) {
> + boolean answer = defaultChecker.isGetterVisible(method);
> + if (answer) {
> + answer = isGetterMethodWithFieldVisible(method, getGetterFieldName(
> + method.getName()), method.getDeclaringClass())
> + && isGetterMethodRetItselfVisible(method, method.getDeclaringClass());
> + }
> + return answer;
> + }
> +
> + @Override
> + public boolean isIsGetterVisible(AnnotatedMethod method) {
> + boolean answer = defaultChecker.isIsGetterVisible(method);
> + if (answer) {
> + answer = isGetterMethodWithFieldVisible(method, getIsGetterFieldName(
> + method.getName()), method.getDeclaringClass())
> + && isGetterMethodRetItselfVisible(method.getMember(), method.getDeclaringClass());
> + }
> + return answer;
> + }
> +
> + @Override
> + public boolean isIsGetterVisible(Method method) {
> + boolean answer = defaultChecker.isIsGetterVisible(method);
> + if (answer) {
> + answer = isGetterMethodWithFieldVisible(method, getIsGetterFieldName(
> + method.getName()), method.getDeclaringClass())
> + && isGetterMethodRetItselfVisible(method, method.getDeclaringClass());
> + }
> + return answer;
> + }
> +
> + protected String getIsGetterFieldName(String methodName) {
> + return Introspector.decapitalize(methodName.substring(2));
> + }
> + protected String getGetterFieldName(String methodName) {
> + return Introspector.decapitalize(methodName.substring(3));
> + }
> +
> + /**
> + * Returns false if the getter method has a field of the same name which is transient
> + * @return
> + */
> + protected boolean isGetterMethodWithFieldVisible(Object method,
> + String fieldName,
> + Class<?> declaringClass) {
> + Field field = findField(fieldName, declaringClass);
> + if (field != null) {
> + int fieldModifiers = field.getModifiers();
> + if (Modifier.isTransient(fieldModifiers)) {
> + if (LOG.isLoggable(Level.FINE)) {
> + LOG.fine("Ignoring getter " + method + " due to transient field called "
> + + fieldName);
> + }
> + return false;
> + }
> + }
> + return true;
> + }
> +
> +
> + /**
> + * Returns false if the getter method just return the declaringClass itself to avoid the
> + * recusive dead loop
> + * @return
> + */
> + protected boolean isGetterMethodRetItselfVisible(Method method,
> + Class<?> declaringClass) {
> + if (method != null && method.getReturnType().getName().equals(declaringClass.getName())) {
> + if (LOG.isLoggable(Level.FINE)) {
> + LOG.fine("Ignoring getter " + method + " due to return same type as declaringClass itself");
> + }
> + return false;
> + }
> + return true;
> + }
> +
> +
> + // Delegated methods
> + //-------------------------------------------------------------------------
> +
> + @Override
> + public boolean isCreatorVisible(AnnotatedMember m) {
> + return defaultChecker.isCreatorVisible(m);
> + }
> +
> + @Override
> + public boolean isCreatorVisible(Member m) {
> + return defaultChecker.isCreatorVisible(m);
> + }
> +
> + @Override
> + public boolean isFieldVisible(AnnotatedField f) {
> + return defaultChecker.isFieldVisible(f);
> + }
> +
> + @Override
> + public boolean isFieldVisible(Field f) {
> + return defaultChecker.isFieldVisible(f);
> + }
> + @Override
> + public boolean isSetterVisible(AnnotatedMethod m) {
> + return defaultChecker.isSetterVisible(m);
> + }
> +
> + @Override
> + public boolean isSetterVisible(Method m) {
> + return defaultChecker.isSetterVisible(m);
> + }
> +
> + @Override
> + public IgnorePropertiesBackedByTransientFields with(JsonAutoDetect ann) {
> + return castToPropertiesBackedByTransientFields(defaultChecker.with(ann));
> + }
> +
> + @Override
> + public IgnorePropertiesBackedByTransientFields with(JsonAutoDetect.Visibility v) {
> + return castToPropertiesBackedByTransientFields(defaultChecker.with(v));
> + }
> +
> + @Override
> + public IgnorePropertiesBackedByTransientFields withCreatorVisibility(JsonAutoDetect.Visibility v) {
> + return castToPropertiesBackedByTransientFields(defaultChecker.withCreatorVisibility(v));
> + }
> +
> + @Override
> + public IgnorePropertiesBackedByTransientFields withFieldVisibility(JsonAutoDetect.Visibility v) {
> + return castToPropertiesBackedByTransientFields(defaultChecker.withFieldVisibility(v));
> + }
> +
> + @Override
> + public IgnorePropertiesBackedByTransientFields withGetterVisibility(JsonAutoDetect.Visibility v) {
> + return castToPropertiesBackedByTransientFields(defaultChecker.withGetterVisibility(v));
> + }
> +
> + @Override
> + public IgnorePropertiesBackedByTransientFields withIsGetterVisibility(JsonAutoDetect.Visibility v) {
> + return castToPropertiesBackedByTransientFields(defaultChecker.withIsGetterVisibility(v));
> + }
> +
> + @Override
> + public IgnorePropertiesBackedByTransientFields withSetterVisibility(JsonAutoDetect.Visibility v) {
> + return castToPropertiesBackedByTransientFields(defaultChecker.withSetterVisibility(v));
> + }
> +
> + @Override
> + public IgnorePropertiesBackedByTransientFields withVisibility(PropertyAccessor method,
> + JsonAutoDetect.Visibility v) {
> + return castToPropertiesBackedByTransientFields(defaultChecker.withVisibility(method, v));
> + }
> +
> +
> + protected IgnorePropertiesBackedByTransientFields castToPropertiesBackedByTransientFields(Object value) {
> + if (value instanceof IgnorePropertiesBackedByTransientFields) {
> + return (IgnorePropertiesBackedByTransientFields) value;
> + } else {
> + if (value != null) {
> + if (value instanceof VisibilityChecker<?>) {
> + return new IgnorePropertiesBackedByTransientFields((VisibilityChecker<?>) value);
> + }
> + LOG.warning("Could not convert value to "
> + + "IgnorePropertiesBackedByTransientFields as was "
> + + value.getClass().getName() + " " + value);
> + }
> + return null;
> + }
> + }
> + protected static Field findField(String fieldName, Class<?> declaringClass) {
> + try {
> + return declaringClass.getDeclaredField(fieldName);
> + } catch (NoSuchFieldException e) {
> + Class<?> superclass = declaringClass.getSuperclass();
> + if (superclass != null && superclass != declaringClass) {
> + return findField(fieldName, superclass);
> + } else {
> + return null;
> + }
> + }
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/JsonSchemaLookup.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/JsonSchemaLookup.java b/core/src/main/java/org/apache/cxf/endpoint/JsonSchemaLookup.java
> new file mode 100644
> index 0000000..8316b24
> --- /dev/null
> +++ b/core/src/main/java/org/apache/cxf/endpoint/JsonSchemaLookup.java
> @@ -0,0 +1,99 @@
> +/**
> + * 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.cxf.endpoint;
> +
> +
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +import com.fasterxml.jackson.databind.ObjectMapper;
> +import com.fasterxml.jackson.databind.ObjectWriter;
> +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
> +
> +import org.apache.cxf.common.logging.LogUtils;
> +
> +
> +
> +public class JsonSchemaLookup {
> +
> + private static final Logger LOG = LogUtils.getL7dLogger(JsonSchemaLookup.class);
> +
> + private static JsonSchemaLookup singleton;
> +
> + private ObjectMapper mapper;
> +
> + public JsonSchemaLookup() {
> + }
> +
> + public static JsonSchemaLookup getSingleton() {
> + if (singleton == null) {
> + // lazy create one
> + new JsonSchemaLookup().init();
> + }
> + return singleton;
> + }
> +
> + public void init() {
> + LOG.log(Level.INFO, "Creating JsonSchemaLookup instance");
> + try {
> + if (mapper == null) {
> + mapper = new ObjectMapper();
> +
> + mapper.setVisibilityChecker(new IgnorePropertiesBackedByTransientFields(mapper.getVisibilityChecker()));
> +
> + JaxbAnnotationModule module1 = new JaxbAnnotationModule();
> + mapper.registerModule(module1);
> +
> + BeanValidationAnnotationModule module2 = new BeanValidationAnnotationModule();
> + mapper.registerModule(module2);
> +
> + }
> + // now lets expose the mbean...
> + singleton = this;
> + } catch (Exception e) {
> + LOG.log(Level.WARNING, "Exception during initialization: ", e);
> + throw new RuntimeException(e);
> + }
> + }
> +
> +
> +
> +
> +
> +
> + public String getSchemaForClass(Class<?> clazz) {
> + LOG.info("Looking up schema for " + clazz.getCanonicalName());
> + String name = clazz.getName();
> + try {
> + ObjectWriter writer = mapper.writer().with(new FourSpacePrettyPrinter());
> + return writer.writeValueAsString(mapper.generateJsonSchema(clazz));
> + } catch (Exception e) {
> + LOG.log(Level.FINEST, "Failed to generate JSON schema for class " + name, e);
> + return "";
> + }
> + }
> +
> + public ObjectMapper getMapper() {
> + return mapper;
> + }
> +
> + public void setMapper(ObjectMapper mapper) {
> + this.mapper = mapper;
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/ManagedEndpoint.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/ManagedEndpoint.java b/core/src/main/java/org/apache/cxf/endpoint/ManagedEndpoint.java
> index de53e8b..380af6d 100644
> --- a/core/src/main/java/org/apache/cxf/endpoint/ManagedEndpoint.java
> +++ b/core/src/main/java/org/apache/cxf/endpoint/ManagedEndpoint.java
> @@ -19,16 +19,43 @@
>
> package org.apache.cxf.endpoint;
>
> +import java.io.BufferedReader;
> +import java.io.IOException;
> +import java.io.StringReader;
> +import java.io.StringWriter;
> +import java.util.Dictionary;
> +import java.util.HashSet;
> +import java.util.List;
> +import java.util.Set;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> import javax.management.JMException;
> import javax.management.ObjectName;
> +import javax.xml.bind.JAXBContext;
> +import javax.xml.bind.Marshaller;
> +
> +import com.fasterxml.jackson.databind.ObjectMapper;
>
> import org.apache.cxf.Bus;
> +import org.apache.cxf.common.logging.LogUtils;
> +import org.apache.cxf.common.util.PackageUtils;
> import org.apache.cxf.common.util.StringUtils;
> +import org.apache.cxf.feature.Feature;
> import org.apache.cxf.management.ManagedComponent;
> import org.apache.cxf.management.ManagementConstants;
> import org.apache.cxf.management.annotation.ManagedAttribute;
> import org.apache.cxf.management.annotation.ManagedOperation;
> import org.apache.cxf.management.annotation.ManagedResource;
> +import org.apache.cxf.service.model.BindingInfo;
> +import org.apache.cxf.service.model.BindingOperationInfo;
> +import org.apache.cxf.service.model.MessagePartInfo;
> +import org.apache.cxf.service.model.ServiceInfo;
> +import org.osgi.framework.BundleContext;
> +import org.osgi.framework.FrameworkUtil;
> +import org.osgi.framework.ServiceReference;
> +import org.osgi.service.cm.Configuration;
> +import org.osgi.service.cm.ConfigurationAdmin;
>
> @ManagedResource(componentName = "Endpoint",
> description = "Responsible for managing server instances.")
> @@ -36,6 +63,10 @@ import org.apache.cxf.management.annotation.ManagedResource;
> public class ManagedEndpoint implements ManagedComponent, ServerLifeCycleListener {
> public static final String ENDPOINT_NAME = "managed.endpoint.name";
> public static final String SERVICE_NAME = "managed.service.name";
> + public static final String INDENTION = " ";
> + private static final Logger LOG = LogUtils.getL7dLogger(ManagedEndpoint.class);
> +
> + private final String eol = System.getProperty("line.separator");
>
> private Bus bus;
> private Endpoint endpoint;
> @@ -43,6 +74,8 @@ public class ManagedEndpoint implements ManagedComponent, ServerLifeCycleListene
> private enum State { CREATED, STARTED, STOPPED };
> private State state = State.CREATED;
>
> + private ConfigurationAdmin configurationAdmin;
> +
> public ManagedEndpoint(Bus b, Endpoint ep, Server s) {
> bus = b;
> endpoint = ep;
> @@ -85,6 +118,497 @@ public class ManagedEndpoint implements ManagedComponent, ServerLifeCycleListene
> public String getState() {
> return state.toString();
> }
> +
> + @ManagedAttribute(description = "The cxf servlet context", currencyTimeLimit = 60)
> + public String getServletContext() {
> + if (!isInOSGi()) {
> + LOG.log(Level.FINE, "Not In OSGi.");
> + return null; //not in OSGi container
> + }
> + String ret = "/cxf"; //if can't get it from configAdmin use the default value
> + if (getConfigurationAdmin() != null) {
> + try {
> + Configuration configuration = getConfigurationAdmin().getConfiguration("org.apache.cxf.osgi");
> + if (configuration != null) {
> + Dictionary properties = configuration.getProperties();
> + if (properties != null) {
> + String servletContext = (String)configuration.getProperties().
> + get("org.apache.cxf.servlet.context");
> + if (servletContext != null) {
> + ret = servletContext;
> + }
> + }
> + }
> + } catch (Exception e) {
> + LOG.log(Level.WARNING, "getServletContext failed.", e);
> + }
> + }
> + return ret;
> + }
> +
> + @ManagedAttribute(description = "if the endpoint has swagger doc or not", currencyTimeLimit = 60)
> + public boolean isSwagger() {
> + if (!isWADL()) {
> + return false;
> + }
> + List<Feature> features = server.getEndpoint().getActiveFeatures();
> + if (features != null) {
> + for (Feature feature : features) {
> + if (feature.getClass().getName().endsWith("SwaggerFeature")) {
> + return true;
> + }
> + }
> + }
> + return false;
> + }
> +
> + @ManagedAttribute(description = "if the endpoint has wsdl doc or not", currencyTimeLimit = 60)
> + public boolean isWSDL() {
> + return !isWADL();
> + }
> +
> + @ManagedAttribute(description = "if the endpoint has WADL doc or not", currencyTimeLimit = 60)
> + public boolean isWADL() {
> + if (endpoint.getEndpointInfo().getBinding().
> + getBindingId().equals("http://apache.org/cxf/binding/jaxrs")) {
> + return true;
> + }
> + return false;
> + }
> +
> + @ManagedOperation(description = "get the JSON schema from a given endpoint", currencyTimeLimit = 60)
> + public String getJSONSchema() {
> + String ret = "";
> + if (!isWSDL()) {
> + Set<Class<?>> resourceTypes = (Set<Class<?>>)endpoint.get("jaxrs.resource.types");
> + if (resourceTypes != null) {
> + try {
> + ret = ret + getBeginIndentionWithReturn(1) + "\""
> + + "definitions" + "\" " + " : {"
> + + getEol();
> + for (Class<?> cls : resourceTypes) {
> + if (JsonSchemaLookup.getSingleton()
> + .getSchemaForClass(cls).length() > 0) {
> + ret = ret + getIndention(2) + "\"" + cls.getName() + "\" : "
> + + getEol();
> +
> + ret = ret
> + + rollbackEol(reformatIndent(JsonSchemaLookup.getSingleton()
> + .getSchemaForClass(cls), 3)) + "," + getEol();
> + }
> +
> + }
> + ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturn(1);
> + ret = ret + getEndIndentionWithReturn(0);
> + } catch (Throwable e) {
> + LOG.log(Level.WARNING, "getJSONSchema failed.", e);
> + }
> + }
> + } else {
> + try {
> + for (ServiceInfo serviceInfo : endpoint.getService().getServiceInfos()) {
> + for (BindingInfo bindingInfo : serviceInfo.getBindings()) {
> + ret = ret + getBeginIndentionWithReturn(1) + "\"operations\" : "
> + + getBeginIndentionWithReturn(0);
> + for (BindingOperationInfo boi : bindingInfo.getOperations()) {
> + ret = ret + getIndention(2) + "\""
> + + boi.getOperationInfo().getName().getLocalPart() + "\" " + " : "
> + + getBeginIndentionWithReturn(3);
> + if (boi.getInput() != null && boi.getInput().getMessageParts() != null) {
> + ret = ret + "\"input\" : " + getBeginIndentionWithReturn(4) + "\"type\" : \""
> + + boi.getOperationInfo().getInput().getName().getLocalPart() + "\""
> + + getEndIndentionWithReturn(3) + "," + getEol();
> +
> + }
> + if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null) {
> + ret = ret + getIndention(3) + "\"output\" : "
> + + getBeginIndentionWithReturn(4) + "\"type\" : \""
> + + boi.getOperationInfo().getOutput().getName().getLocalPart() + "\""
> + + getEndIndentionWithReturn(3);
> + }
> + ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturn(2) + "," + getEol();
> + }
> + if (ret.length() > 0) {
> + ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturn(1) + ",";
> + }
> + Set<String> addedType = new HashSet<String>();
> +
> + ret = ret + getEol() + getIndention(1) + "\"definitions\" : "
> + + getBeginIndentionWithReturn(0);
> + for (BindingOperationInfo boi : bindingInfo.getOperations()) {
> +
> + if (boi.getInput() != null && boi.getInput().getMessageParts() != null
> + && !addedType.contains(boi.getOperationInfo().getInput().getName().getLocalPart())) {
> +
> + ret = ret + getIndention(2) + "\""
> + + boi.getOperationInfo().getInput().getName().getLocalPart() + "\" : "
> + + getBeginIndentionWithReturnForList(0);
> + for (MessagePartInfo mpi : boi.getInput().getMessageParts()) {
> + Class<?> partClass = mpi.getTypeClass();
> + if (partClass != null) {
> + ret = ret
> + + rollbackEol(reformatIndent(JsonSchemaLookup.getSingleton()
> + .getSchemaForClass(partClass), 3)) + "," + getEol();
> + }
> + }
> + ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturnForList(2)
> + + "," + getEol();
> + addedType.add(boi.getOperationInfo().getInput().getName().getLocalPart());
> +
> + }
> + if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null
> + && !addedType.contains(boi.getOperationInfo().getOutput().getName().getLocalPart())) {
> +
> + ret = ret + getIndention(2) + "\""
> + + boi.getOperationInfo().getOutput().getName().getLocalPart()
> + + "\" : " + getBeginIndentionWithReturnForList(0);
> +
> + for (MessagePartInfo mpi : boi.getOutput().getMessageParts()) {
> + Class<?> partClass = mpi.getTypeClass();
> + if (partClass != null) {
> + ret = ret
> + + rollbackEol(reformatIndent(JsonSchemaLookup.getSingleton()
> + .getSchemaForClass(partClass), 3)) + "," + getEol();
> + }
> + }
> + ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturnForList(2)
> + + "," + getEol();
> + addedType.add(boi.getOperationInfo().getOutput().getName().getLocalPart());
> +
> + }
> + }
> + if (ret.length() > 0) {
> + ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturn(1);
> + }
> +
> + if (ret.length() > 0) {
> + ret = rollbackColon(ret) + getEndIndentionWithReturn(0);
> + }
> + }
> + }
> +
> + } catch (Throwable e) {
> + LOG.log(Level.WARNING, "getJSONSchema failed.", e);
> + }
> + }
> + return ret;
> + }
> +
> + @ManagedOperation(description = "get the JSON schema from a given class", currencyTimeLimit = 60)
> + public String getJSONSchemaForClass(String clsName) {
> + String ret = "";
> + if (!isWSDL()) {
> + Set<Class<?>> resourceTypes = (Set<Class<?>>)endpoint.get("jaxrs.resource.types");
> + if (resourceTypes != null) {
> + try {
> + ret = ret + getBeginIndentionWithReturn(1) + "\""
> + + "definitions" + "\" " + " : {"
> + + getEol();
> + for (Class<?> cls : resourceTypes) {
> + if (cls.getName().endsWith(clsName)
> + && JsonSchemaLookup.getSingleton().getSchemaForClass(cls).length() > 0) {
> + ret = ret + getIndention(2) + "\"" + cls.getName() + "\" : "
> + + getEol();
> +
> + ret = ret
> + + reformatIndent(JsonSchemaLookup.getSingleton().getSchemaForClass(cls), 3);
> + ret = ret + getEol();
> + }
> + }
> + ret = ret + getEndIndentionWithReturn(1);
> + ret = ret + getEndIndentionWithReturn(0);
> + } catch (Throwable e) {
> + LOG.log(Level.WARNING, "getJSONSchemaForClass failed.", e);
> + }
> + }
> + } else {
> +
> + for (ServiceInfo serviceInfo : endpoint.getService().getServiceInfos()) {
> + for (BindingInfo bindingInfo : serviceInfo.getBindings()) {
> + ret = ret + getBeginIndentionWithReturn(1) + "\""
> + + "definitions" + "\" " + " : {"
> + + getEol();
> + for (BindingOperationInfo boi : bindingInfo.getOperations()) {
> +
> + if (boi.getInput() != null && boi.getInput().getMessageParts() != null) {
> + for (MessagePartInfo mpi : boi.getInput().getMessageParts()) {
> + Class<?> partClass = mpi.getTypeClass();
> + if (partClass != null && partClass.getName().endsWith(clsName)) {
> + ret = ret + getIndention(2) + "\"" + partClass.getName() + "\" : "
> + + getEol();
> +
> + ret = ret
> + + reformatIndent(JsonSchemaLookup.getSingleton()
> + .getSchemaForClass(partClass), 3);
> + }
> + }
> +
> + }
> + if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null) {
> + for (MessagePartInfo mpi : boi.getOutput().getMessageParts()) {
> + Class<?> partClass = mpi.getTypeClass();
> + if (partClass != null && partClass.getName().endsWith(clsName)) {
> + ret = ret + getIndention(2) + "\"" + partClass.getName() + "\" : "
> + + getEol();
> +
> + ret = ret
> + + reformatIndent(JsonSchemaLookup.getSingleton()
> + .getSchemaForClass(partClass), 3);
> + }
> + }
> + }
> + }
> + ret = ret + getEndIndentionWithReturn(1);
> + ret = ret + getEndIndentionWithReturn(0);
> + }
> + }
> +
> + }
> + return ret;
> + }
> +
> + @ManagedOperation(description = "get the JSON schema from a given soap endpoint for a given operation",
> + currencyTimeLimit = 60)
> + public String getJSONSchemaForOperation(String operationName) {
> + if (!isWSDL()) {
> + return null;
> + }
> + String ret = "";
> +
> + for (ServiceInfo serviceInfo : endpoint.getService().getServiceInfos()) {
> + for (BindingInfo bindingInfo : serviceInfo.getBindings()) {
> + for (BindingOperationInfo boi : bindingInfo.getOperations()) {
> + if (operationName.equals(boi.getOperationInfo().getName().getLocalPart())) {
> + ret = ret + getBeginIndentionWithReturn(1) + "\""
> + + boi.getOperationInfo().getName().getLocalPart() + "\" " + " : "
> + + getBeginIndentionWithReturn(2);
> + if (boi.getInput() != null && boi.getInput().getMessageParts() != null) {
> + ret = ret + "\"input\" : " + getBeginIndentionWithReturn(4) + "\"type\" : \""
> + + boi.getOperationInfo().getInput().getName().getLocalPart() + "\""
> + + getEndIndentionWithReturn(2) + "," + getEol();
> +
> + }
> + if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null) {
> + ret = ret + getIndention(2) + "\"output\" : " + getBeginIndentionWithReturn(4)
> + + "\"type\" : \"" + boi.getOperationInfo().getOutput().getName().getLocalPart() + "\""
> + + getEndIndentionWithReturn(2);
> + }
> + ret = rollbackColon(ret) + getEndIndentionWithReturn(1) + ",";
> +
> + ret = ret + getEol() + getIndention(1) + "\"definitions\" : "
> + + getBeginIndentionWithReturn(2);
> + if (boi.getInput() != null && boi.getInput().getMessageParts() != null) {
> + ret = ret + "\"" + boi.getOperationInfo().getInput().getName().getLocalPart() + "\" : "
> + + getBeginIndentionWithReturnForList(0);
> + for (MessagePartInfo mpi : boi.getInput().getMessageParts()) {
> + Class<?> partClass = mpi.getTypeClass();
> + if (partClass != null) {
> + ret = ret
> + + rollbackEol(reformatIndent(JsonSchemaLookup.getSingleton()
> + .getSchemaForClass(partClass), 3)) + "," + getEol();
> + }
> + }
> + ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturnForList(2)
> + + "," + getEol();
> + }
> + if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null) {
> + ret = ret + getIndention(2) + "\""
> + + boi.getOperationInfo().getOutput().getName().getLocalPart()
> + + "\" : " + getBeginIndentionWithReturnForList(0);
> +
> + for (MessagePartInfo mpi : boi.getOutput().getMessageParts()) {
> + Class<?> partClass = mpi.getTypeClass();
> + if (partClass != null) {
> + ret = ret
> + + rollbackEol(reformatIndent(JsonSchemaLookup.getSingleton()
> + .getSchemaForClass(partClass), 3)) + "," + getEol();
> + }
> + }
> + ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturnForList(2) + ",";
> + }
> +
> + }
> +
> + }
> + if (ret.length() > 0) {
> + ret = rollbackColon(ret) + getEndIndentionWithReturn(1);
> + }
> +
> + if (ret.length() > 0) {
> + ret = rollbackColon(ret) + getEndIndentionWithReturn(0);
> + }
> + }
> + }
> + return ret;
> + }
> +
> + @ManagedOperation(description = "get the package name for a given namespace URI", currencyTimeLimit = 60)
> + public String getPackageNameByNameSpaceURI(String nameSpaceURI) {
> + return PackageUtils.getPackageNameByNameSpaceURI(nameSpaceURI);
> + }
> +
> + @ManagedOperation(description = "get xml payload from json payload", currencyTimeLimit = 60)
> + public String jsonToXml(String jsonText, String pojoType) {
> + ObjectMapper objectMapper = new ObjectMapper();
> + StringWriter sw = new StringWriter();
> + try {
> + Object pojo = objectMapper.readValue(jsonText, findClass(pojoType));
> + JAXBContext jc = JAXBContext.newInstance(findClass(pojoType));
> + Marshaller marshaller = jc.createMarshaller();
> + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
> + marshaller.marshal(pojo, sw);
> + } catch (Exception e) {
> + LOG.log(Level.WARNING, "jsonToXml failed.", e);
> + }
> +
> + return sw.toString();
> + }
> +
> + private Class<?> findClass(String clsName) {
> + if (!isWSDL()) {
> + Set<Class<?>> resourceTypes = (Set<Class<?>>)endpoint.get("jaxrs.resource.types");
> + if (resourceTypes != null) {
> + try {
> +
> + for (Class<?> cls : resourceTypes) {
> + if (cls.getName().endsWith(clsName)) {
> + return cls;
> + }
> + }
> +
> + } catch (Throwable e) {
> + LOG.log(Level.WARNING, "findClass failed.", e);
> + }
> + }
> + } else {
> +
> + for (ServiceInfo serviceInfo : endpoint.getService().getServiceInfos()) {
> + for (BindingInfo bindingInfo : serviceInfo.getBindings()) {
> + for (BindingOperationInfo boi : bindingInfo.getOperations()) {
> +
> + if (boi.getInput() != null && boi.getInput().getMessageParts() != null) {
> + for (MessagePartInfo mpi : boi.getInput().getMessageParts()) {
> + Class<?> partClass = mpi.getTypeClass();
> + if (partClass != null && partClass.getName().endsWith(clsName)) {
> + return partClass;
> + }
> + }
> +
> + }
> + if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null) {
> + for (MessagePartInfo mpi : boi.getOutput().getMessageParts()) {
> + Class<?> partClass = mpi.getTypeClass();
> + if (partClass != null && partClass.getName().endsWith(clsName)) {
> + return partClass;
> + }
> + }
> + }
> + }
> + }
> + }
> +
> + }
> + return null;
> + }
> +
> + private String reformatIndent(String input, int startIndent) {
> + String ret = "";
> + BufferedReader reader = new BufferedReader(new StringReader(input));
> + try {
> + String oneLine;
> + while ((oneLine = reader.readLine()) != null) {
> + ret = ret + getIndention(startIndent) + oneLine + getEol();
> + }
> + } catch (IOException e) {
> + LOG.log(Level.WARNING, "reformatIndent failed.", e);
> + }
> + return ret;
> + }
> +
> + private String rollbackEol(String input) {
> + String ret = input;
> + if (ret.endsWith(getEol())) {
> + ret = ret.substring(0, ret.length() - getEol().length());
> + }
> + return ret;
> + }
> +
> + private String rollbackColon(String input) {
> + String ret = input;
> + if (ret.endsWith(",")) {
> + ret = ret.substring(0, ret.length() - 1);
> + }
> + return ret;
> + }
> +
> + private boolean isInOSGi() {
> + if (FrameworkUtil.getBundle(ManagedEndpoint.class) != null) {
> + return true;
> + }
> + return false;
> +
> + }
> +
> +
> + private String getBeginIndentionWithReturn(int n) {
> + return "{" + getEol() + getIndention(n);
> + }
> +
> + private String getEndIndentionWithReturn(int n) {
> + return getEol() + getIndention(n) + "}";
> + }
> +
> + private String getBeginIndentionWithReturnForList(int n) {
> + return "[" + getEol() + getIndention(n);
> + }
> +
> + private String getEndIndentionWithReturnForList(int n) {
> + return getEol() + getIndention(n) + "]";
> + }
> +
> + /*private String getEndIndentionWithoutReturnForList(int n) {
> + return getIndention(n) + "]";
> + }
> +
> + private String getEndIndentionWithoutReturn(int n) {
> + return getIndention(n) + "}";
> + }*/
> +
> + private String getIndention(int n) {
> + String ret = "";
> + for (int i = 0; i < n; i++) {
> + ret = ret + INDENTION;
> + }
> + return ret;
> + }
> +
> + private String getEol() {
> + if (eol == null) {
> + return "\n";
> + } else {
> + return this.eol;
> + }
> + }
> +
> + private ConfigurationAdmin getConfigurationAdmin() {
> + try {
> + if (isInOSGi() && (configurationAdmin == null)) {
> + BundleContext bundleContext = FrameworkUtil.getBundle(ManagedEndpoint.class)
> + .getBundleContext();
> + if (bundleContext != null) {
> + ServiceReference serviceReference = bundleContext
> + .getServiceReference(ConfigurationAdmin.class.getName());
> + if (serviceReference != null) {
> + configurationAdmin = (ConfigurationAdmin)bundleContext.getService(serviceReference);
> + }
> + }
> +
> + }
> + } catch (Exception e) {
> + LOG.log(Level.WARNING, "getConfigurationAdmin failed.", e);
> + }
> + return configurationAdmin;
> + }
>
> public ObjectName getObjectName() throws JMException {
> String busId = bus.getId();
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/parent/pom.xml
> ----------------------------------------------------------------------
> diff --git a/parent/pom.xml b/parent/pom.xml
> index 419d3f4..c128469 100644
> --- a/parent/pom.xml
> +++ b/parent/pom.xml
> @@ -188,6 +188,7 @@
> <cxf.dom4j.bundle.version>1.6.1_5</cxf.dom4j.bundle.version>
> <cxf.jdom.bundle.version>1.1_4</cxf.jdom.bundle.version>
> <cxf.olingo.version>1.1.0</cxf.olingo.version>
> + <cxf.jackson.version>2.3.0-rc1</cxf.jackson.version>
> <cxf.checkstyle.extension />
> <cxf.jaxb.context.class />
> <cxf.spring.validation.mode>VALIDATION_AUTO</cxf.spring.validation.mode>
> @@ -1616,7 +1617,26 @@
> <artifactId>swagger-jaxrs_2.10</artifactId>
> <version>${cxf.swagger.version}</version>
> </dependency>
> -
> + <dependency>
> + <groupId>com.fasterxml.jackson.module</groupId>
> + <artifactId>jackson-module-jaxb-annotations</artifactId>
> + <version>${cxf.jackson.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>com.fasterxml.jackson.core</groupId>
> + <artifactId>jackson-databind</artifactId>
> + <version>${cxf.jackson.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>com.fasterxml.jackson.core</groupId>
> + <artifactId>jackson-annotations</artifactId>
> + <version>${cxf.jackson.version}</version>
> + </dependency>
> + <dependency>
> + <groupId>com.fasterxml.jackson.core</groupId>
> + <artifactId>jackson-core</artifactId>
> + <version>${cxf.jackson.version}</version>
> + </dependency>
> </dependencies>
> </dependencyManagement>
> <profiles>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java
> ----------------------------------------------------------------------
> diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java
> index 4ee0127..e8e1f1a 100644
> --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java
> +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java
> @@ -18,12 +18,14 @@
> */
> package org.apache.cxf.jaxrs;
>
> +import java.lang.reflect.Type;
> import java.util.ArrayList;
> import java.util.Arrays;
> import java.util.Collections;
> import java.util.Iterator;
> import java.util.LinkedList;
> import java.util.List;
> +import java.util.Map;
> import java.util.ResourceBundle;
> import java.util.logging.Logger;
>
> @@ -66,7 +68,8 @@ public class AbstractJAXRSFactoryBean extends AbstractEndpointFactory {
>
> private static final Logger LOG = LogUtils.getL7dLogger(AbstractJAXRSFactoryBean.class);
> private static final ResourceBundle BUNDLE = BundleUtils.getBundle(AbstractJAXRSFactoryBean.class);
> -
> + private static final String RESOURCE_TYPES = "jaxrs.resource.types";
> +
> protected List<String> schemaLocations;
> protected JAXRSServiceFactoryBean serviceFactory;
> protected List<Object> entityProviders = new LinkedList<Object>();
> @@ -241,6 +244,9 @@ public class AbstractJAXRSFactoryBean extends AbstractEndpointFactory {
> cri.getServiceClass(), null);
> }
> ep.put(JAXRSServiceFactoryBean.class.getName(), serviceFactory);
> + Map<Class<?>, Type> allClasses =
> + ResourceUtils.getAllRequestResponseTypes(list, false).getAllTypes();
> + ep.put(RESOURCE_TYPES, allClasses.keySet());
> return ep;
> }
>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/rt/pom.xml
> ----------------------------------------------------------------------
> diff --git a/rt/pom.xml b/rt/pom.xml
> index 8472491..761cedc 100644
> --- a/rt/pom.xml
> +++ b/rt/pom.xml
> @@ -49,7 +49,6 @@
> <module>transports/http-netty/netty-server</module>
> <module>transports/http-netty/netty-client</module>
> <module>transports/jms</module>
> - <module>transports/udp</module>
> <module>transports/websocket</module>
> <module>ws/policy</module>
> <module>ws/addr</module>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
> ----------------------------------------------------------------------
> diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
> index a773a9f..c72af89 100644
> --- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
> +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
> @@ -205,6 +205,18 @@ public class WadlGenerator implements ContainerRequestFilter {
>
> boolean isJson = type == MediaType.APPLICATION_JSON_TYPE;
>
> + StringBuilder sbMain = generateWADL(getBaseURI(m, ui), getResourcesList(m, ui), isJson, m, ui);
> +
> + m.getExchange().put(JAXRSUtils.IGNORE_MESSAGE_WRITERS, !isJson && ignoreMessageWriters);
> + Response r = Response.ok().type(type).entity(createResponseEntity(sbMain.toString(), isJson)).build();
> + context.abortWith(r);
> + }
> +
> + public StringBuilder generateWADL(String baseURI,
> + List<ClassResourceInfo> cris,
> + boolean isJson,
> + Message m,
> + UriInfo ui) {
> StringBuilder sbMain = new StringBuilder();
> sbMain.append("<application");
> if (!isJson) {
> @@ -215,11 +227,10 @@ public class WadlGenerator implements ContainerRequestFilter {
> sbGrammars.append("<grammars>");
>
> StringBuilder sbResources = new StringBuilder();
> - sbResources.append("<resources base=\"").append(getBaseURI(m, ui)).append("\">");
> + sbResources.append("<resources base=\"").append(baseURI).append("\">");
>
> - List<ClassResourceInfo> cris = getResourcesList(m, ui);
> -
> - MessageBodyWriter<?> jaxbWriter = useJaxbContextForQnames
> +
> + MessageBodyWriter<?> jaxbWriter = (m != null && useJaxbContextForQnames)
> ? ServerProviderFactory.getInstance(m).getRegisteredJaxbWriter() : null;
> ResourceTypes resourceTypes = ResourceUtils.getAllRequestResponseTypes(cris,
> useJaxbContextForQnames,
> @@ -262,10 +273,7 @@ public class WadlGenerator implements ContainerRequestFilter {
> sbMain.append(sbGrammars.toString());
> sbMain.append(sbResources.toString());
> sbMain.append("</application>");
> -
> - m.getExchange().put(JAXRSUtils.IGNORE_MESSAGE_WRITERS, !isJson && ignoreMessageWriters);
> - Response r = Response.ok().type(type).entity(createResponseEntity(sbMain.toString(), isJson)).build();
> - context.abortWith(r);
> + return sbMain;
> }
>
> private Object createResponseEntity(String entity, boolean isJson) {
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java
> ----------------------------------------------------------------------
> diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java
> index 85e3dd3..c772559 100644
> --- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java
> +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java
> @@ -22,8 +22,11 @@ import java.util.ArrayList;
> import java.util.List;
>
> import org.apache.cxf.Bus;
> +import org.apache.cxf.endpoint.EndpointImpl;
> import org.apache.cxf.endpoint.Server;
> import org.apache.cxf.feature.AbstractFeature;
> +import org.apache.cxf.feature.Feature;
> +import org.apache.cxf.interceptor.InterceptorProvider;
> import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean;
> import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
> import org.apache.cxf.jaxrs.provider.ProviderFactory;
> @@ -80,6 +83,21 @@ public class SwaggerFeature extends AbstractFeature {
> setBasePath(address + "/api-docs");
> }
> }
> +
> + @Override
> + protected void initializeProvider(InterceptorProvider provider, Bus bus) {
> + EndpointImpl endpointImpl = (EndpointImpl)provider;
> + List<Feature> features = endpointImpl.getActiveFeatures();
> + if (features == null) {
> + features = new ArrayList<Feature>();
> + features.add(this);
> + endpointImpl.initializeActiveFeatures(features);
> + } else {
> + features.add(this);
> + }
> + }
> +
> +
> public String getResourcePackage() {
> return resourcePackage;
> }
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/services/pom.xml
> ----------------------------------------------------------------------
> diff --git a/services/pom.xml b/services/pom.xml
> index f7b49d4..34c3c09 100644
> --- a/services/pom.xml
> +++ b/services/pom.xml
> @@ -31,7 +31,6 @@
> <version>3.0.0-SNAPSHOT</version>
> </parent>
> <modules>
> - <module>sts</module>
> <module>wsn</module>
> <module>ws-discovery</module>
> <module>xkms</module>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/services/xkms/pom.xml
> ----------------------------------------------------------------------
> diff --git a/services/xkms/pom.xml b/services/xkms/pom.xml
> index e7c9fa7..14d6011 100644
> --- a/services/xkms/pom.xml
> +++ b/services/xkms/pom.xml
> @@ -39,6 +39,5 @@
> <module>xkms-features</module>
> <module>xkms-osgi</module>
> <module>xkms-war</module>
> - <module>xkms-itests</module>
> </modules>
> </project>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxrs/pom.xml
> ----------------------------------------------------------------------
> diff --git a/systests/jaxrs/pom.xml b/systests/jaxrs/pom.xml
> index 6f66d90..81f7ec0 100644
> --- a/systests/jaxrs/pom.xml
> +++ b/systests/jaxrs/pom.xml
> @@ -415,6 +415,27 @@
> <version>${cxf.netty3.version}</version>
> <scope>test</scope>
> </dependency>
> + <dependency>
> + <groupId>com.fasterxml.jackson.core</groupId>
> + <artifactId>jackson-core</artifactId>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>com.fasterxml.jackson.core</groupId>
> + <artifactId>jackson-databind</artifactId>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>com.fasterxml.jackson.module</groupId>
> + <artifactId>jackson-module-jaxb-annotations</artifactId>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>javax.validation</groupId>
> + <artifactId>validation-api</artifactId>
> + <scope>test</scope>
> + </dependency>
> +
> </dependencies>
> <build>
> <plugins>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/RestJsonSchemaJMXTest.java
> ----------------------------------------------------------------------
> diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/RestJsonSchemaJMXTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/RestJsonSchemaJMXTest.java
> new file mode 100644
> index 0000000..04926c7
> --- /dev/null
> +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/RestJsonSchemaJMXTest.java
> @@ -0,0 +1,162 @@
> +/**
> + * 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.cxf.systest.jaxrs;
> +
> +
> +import java.io.IOException;
> +import java.util.Iterator;
> +import java.util.Set;
> +import java.util.logging.Logger;
> +
> +import javax.management.MBeanServerConnection;
> +import javax.management.MalformedObjectNameException;
> +import javax.management.ObjectName;
> +import javax.management.remote.JMXConnector;
> +import javax.management.remote.JMXConnectorFactory;
> +import javax.management.remote.JMXServiceURL;
> +
> +import com.fasterxml.jackson.core.JsonFactory;
> +import com.fasterxml.jackson.core.JsonParser;
> +
> +import org.apache.cxf.Bus;
> +import org.apache.cxf.BusFactory;
> +import org.apache.cxf.bus.spring.SpringBusFactory;
> +import org.apache.cxf.common.logging.LogUtils;
> +import org.apache.cxf.endpoint.Server;
> +import org.apache.cxf.helpers.CastUtils;
> +import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
> +import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
> +import org.apache.cxf.management.ManagementConstants;
> +import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
> +import org.apache.cxf.transport.local.LocalTransportFactory;
> +
> +import org.junit.After;
> +import org.junit.Before;
> +import org.junit.Test;
> +
> +public class RestJsonSchemaJMXTest extends AbstractBusClientServerTestBase {
> +
> + private static MBeanServerConnection mbsc;
> + private static final String DEFAULT_JMXSERVICE_URL =
> + "service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi";
> + private static final Logger LOG = LogUtils.getL7dLogger(RestJsonSchemaJMXTest.class);
> +
> +
> + private String jmxServerURL;
> +
> + private Server localServer;
> +
> + @Before
> + public void setUp() {
> + SpringBusFactory bf = new SpringBusFactory();
> + Bus bus = bf
> + .createBus("/org/apache/cxf/systest/jaxrs/jmx-enable.xml");
> + BusFactory.setDefaultBus(bus);
> + JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
> + sf.setResourceClasses(BookStore.class, BookStoreSpring.class);
> + sf.setResourceProvider(BookStore.class,
> + new SingletonResourceProvider(new BookStore(), true));
> + sf.setResourceProvider(BookStoreSpring.class,
> + new SingletonResourceProvider(new BookStoreSpring(), true));
> + sf.setTransportId(LocalTransportFactory.TRANSPORT_ID);
> + sf.setAddress("local://books");
> + localServer = sf.create();
> + }
> +
> + @After
> + public void tearDown() {
> + if (localServer != null) {
> + localServer.stop();
> + }
> + }
> +
> + @Test
> + public void testJsonSchema() throws Exception {
> + String json = "";
> + try {
> + connectToMBserver();
> + //test getJSONSchema
> + json = invokeEndpoint("getJSONSchema", null);
> + parseJson(json);
> +
> + //test getJSONSchemaForClass
> + json = invokeEndpoint("getJSONSchemaForClass", "org.apache.cxf.systest.jaxrs.Book");
> + parseJson(json);
> + } catch (Throwable e) {
> + e.printStackTrace();
> + fail("invalid json for " + json);
> + }
> + }
> +
> + private void connectToMBserver() throws IOException {
> + jmxServerURL = jmxServerURL == null ? DEFAULT_JMXSERVICE_URL : jmxServerURL;
> + JMXServiceURL url = new JMXServiceURL(jmxServerURL);
> + JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
> + mbsc = jmxc.getMBeanServerConnection();
> + }
> +
> + private ObjectName getEndpointObjectName()
> + throws MalformedObjectNameException, NullPointerException {
> + StringBuilder buffer = new StringBuilder();
> + String serviceName = "{http://jaxrs.systest.cxf.apache.org/}BookStore";
> + String portName = "BookStore";
> + buffer.append(ManagementConstants.DEFAULT_DOMAIN_NAME + ":type=Bus.Service.Endpoint,");
> + buffer.append(ManagementConstants.SERVICE_NAME_PROP + "=\"" + serviceName + "\",");
> + buffer.append(ManagementConstants.PORT_NAME_PROP + "=\"" + portName + "\",*");
> + return new ObjectName(buffer.toString());
> + }
> +
> + private String invokeEndpoint(String operation, String operationPara)
> + throws Exception {
> + ObjectName endpointName = null;
> + ObjectName queryEndpointName;
> + String ret = "";
> + Object[] jmxPara = null;
> + String[] jmxSig = null;
> + if (operationPara != null) {
> + jmxPara = new Object[]{operationPara};
> + jmxSig = new String[] {String.class.getName()};
> + } else {
> + jmxPara = new Object[0];
> + jmxSig = new String[0];
> + }
> + queryEndpointName = getEndpointObjectName();
> + Set<ObjectName> endpointNames = CastUtils.cast(mbsc.queryNames(queryEndpointName, null));
> + // now get the ObjectName with the busId
> + Iterator<ObjectName> it = endpointNames.iterator();
> +
> + if (it.hasNext()) {
> + // only deal with the first endpoint object which retrun from the list.
> + endpointName = it.next();
> + ret = (String)mbsc.invoke(endpointName, operation, jmxPara, jmxSig);
> + LOG.info("invoke endpoint " + endpointName
> + + " operation " + operation + " succeed!");
> + }
> + return ret;
> + }
> +
> + private void parseJson(String json) throws Exception {
> + JsonParser parser = new JsonFactory().createParser(json);
> + while (parser.nextToken() != null) {
> + //if it's an invalidate json will throw exception
> + //which could be caught by the test
> + }
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jmx-enable.xml
> ----------------------------------------------------------------------
> diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jmx-enable.xml b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jmx-enable.xml
> new file mode 100644
> index 0000000..da799fd
> --- /dev/null
> +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jmx-enable.xml
> @@ -0,0 +1,16 @@
> +<beans xmlns="http://www.springframework.org/schema/beans"
> + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> + xmlns:cxf="http://cxf.apache.org/core"
> + xsi:schemaLocation="
> + http://www.springframework.org/schema/beans
> + http://www.springframework.org/schema/beans/spring-beans.xsd
> + http://cxf.apache.org/core
> + http://cxf.apache.org/schemas/core.xsd">
> +
> + <cxf:bus bus="cxf">
> + <cxf:properties>
> + <entry key="bus.jmx.enabled" value="true"/>
> + <entry key="bus.jmx.JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi" />
> + </cxf:properties>
> + </cxf:bus>
> +</beans>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxws/pom.xml
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/pom.xml b/systests/jaxws/pom.xml
> index d8ee05f..2802d23 100644
> --- a/systests/jaxws/pom.xml
> +++ b/systests/jaxws/pom.xml
> @@ -224,6 +224,27 @@
> </exclusions>
> <scope>test</scope>
> </dependency>
> + <dependency>
> + <groupId>com.fasterxml.jackson.core</groupId>
> + <artifactId>jackson-core</artifactId>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>com.fasterxml.jackson.core</groupId>
> + <artifactId>jackson-databind</artifactId>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>com.fasterxml.jackson.module</groupId>
> + <artifactId>jackson-module-jaxb-annotations</artifactId>
> + <scope>test</scope>
> + </dependency>
> + <dependency>
> + <groupId>javax.validation</groupId>
> + <artifactId>validation-api</artifactId>
> + <scope>test</scope>
> + </dependency>
> +
> </dependencies>
> <profiles>
> <profile>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/JsonSchemaJMXTest.java
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/JsonSchemaJMXTest.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/JsonSchemaJMXTest.java
> new file mode 100644
> index 0000000..ec5b2c0
> --- /dev/null
> +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/JsonSchemaJMXTest.java
> @@ -0,0 +1,146 @@
> +/**
> + * 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.cxf.systest.jaxws;
> +
> +import java.io.IOException;
> +import java.util.Iterator;
> +import java.util.Set;
> +import java.util.logging.Logger;
> +
> +import javax.management.MBeanServerConnection;
> +import javax.management.MalformedObjectNameException;
> +import javax.management.ObjectName;
> +import javax.management.remote.JMXConnector;
> +import javax.management.remote.JMXConnectorFactory;
> +import javax.management.remote.JMXServiceURL;
> +import javax.xml.ws.Endpoint;
> +
> +import com.fasterxml.jackson.core.JsonFactory;
> +import com.fasterxml.jackson.core.JsonParser;
> +
> +import org.apache.cxf.Bus;
> +import org.apache.cxf.BusFactory;
> +import org.apache.cxf.bus.spring.SpringBusFactory;
> +import org.apache.cxf.common.logging.LogUtils;
> +import org.apache.cxf.helpers.CastUtils;
> +import org.apache.cxf.management.ManagementConstants;
> +import org.apache.cxf.testutil.common.TestUtil;
> +
> +import org.apache.hello_world.GreeterImpl;
> +
> +
> +import org.junit.Assert;
> +import org.junit.Test;
> +
> +public class JsonSchemaJMXTest extends Assert {
> +
> + static final String PORT = TestUtil.getPortNumber(JsonSchemaJMXTest.class);
> + private static MBeanServerConnection mbsc;
> + private static final String DEFAULT_JMXSERVICE_URL =
> + "service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi";
> + private static final Logger LOG = LogUtils.getL7dLogger(JsonSchemaJMXTest.class);
> +
> +
> + private String jmxServerURL;
> +
> + @Test
> + public void testJMXGetJsonSchema() throws Exception {
> + SpringBusFactory bf = new SpringBusFactory();
> + Bus bus = bf
> + .createBus("/org/apache/cxf/systest/jaxws/jmx-enable.xml");
> + BusFactory.setDefaultBus(bus);
> + Endpoint ep = Endpoint.publish("http://localhost:" + PORT + "/SoapContext/SoapPort",
> + new GreeterImpl());
> + String json = "";
> + try {
> + connectToMBserver();
> + //test getJSONSchema
> + json = invokeEndpoint("getJSONSchema", null);
> + parseJson(json);
> + //test getJSONSchemaForClass
> + json = invokeEndpoint("getJSONSchemaForClass", "SayHi");
> + parseJson(json);
> + //test getJSONSchemaForOperation
> + json = invokeEndpoint("getJSONSchemaForOperation", "greetMe");
> + parseJson(json);
> + } catch (Throwable e) {
> + e.printStackTrace();
> + fail("invalid json for " + json);
> + } finally {
> + ep.stop();
> + }
> + }
> +
> + private void connectToMBserver() throws IOException {
> + jmxServerURL = jmxServerURL == null ? DEFAULT_JMXSERVICE_URL : jmxServerURL;
> + JMXServiceURL url = new JMXServiceURL(jmxServerURL);
> + JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
> + mbsc = jmxc.getMBeanServerConnection();
> + }
> +
> + private ObjectName getEndpointObjectName()
> + throws MalformedObjectNameException, NullPointerException {
> + StringBuilder buffer = new StringBuilder();
> + String serviceName = "{http://apache.org/hello_world/services}SOAPService";
> + String portName = "SoapPort";
> + buffer.append(ManagementConstants.DEFAULT_DOMAIN_NAME + ":type=Bus.Service.Endpoint,");
> + buffer.append(ManagementConstants.SERVICE_NAME_PROP + "=\"" + serviceName + "\",");
> + buffer.append(ManagementConstants.PORT_NAME_PROP + "=\"" + portName + "\",*");
> + return new ObjectName(buffer.toString());
> + }
> +
> + private String invokeEndpoint(String operation, String operationPara)
> + throws Exception {
> + ObjectName endpointName = null;
> + ObjectName queryEndpointName;
> + String ret = "";
> + Object[] jmxPara = null;
> + String[] jmxSig = null;
> + if (operationPara != null) {
> + jmxPara = new Object[]{operationPara};
> + jmxSig = new String[] {String.class.getName()};
> + } else {
> + jmxPara = new Object[0];
> + jmxSig = new String[0];
> + }
> + queryEndpointName = getEndpointObjectName();
> + Set<ObjectName> endpointNames = CastUtils.cast(mbsc.queryNames(queryEndpointName, null));
> + // now get the ObjectName with the busId
> + Iterator<ObjectName> it = endpointNames.iterator();
> +
> + if (it.hasNext()) {
> + // only deal with the first endpoint object which retrun from the list.
> + endpointName = it.next();
> + ret = (String)mbsc.invoke(endpointName, operation, jmxPara, jmxSig);
> + LOG.info("invoke endpoint " + endpointName
> + + " operation " + operation + " succeed!");
> + }
> + return ret;
> + }
> +
> + private void parseJson(String json) throws Exception {
> + JsonParser parser = new JsonFactory().createParser(json);
> + while (parser.nextToken() != null) {
> + //if it's an invalidate json will throw exception
> + //which could be caught by the test
> + }
> + }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/jmx-enable.xml
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/jmx-enable.xml b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/jmx-enable.xml
> new file mode 100644
> index 0000000..fad676d
> --- /dev/null
> +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/jmx-enable.xml
> @@ -0,0 +1,28 @@
> +<beans xmlns="http://www.springframework.org/schema/beans"
> + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> + xmlns:sec="http://cxf.apache.org/configuration/security"
> + xmlns:http="http://cxf.apache.org/transports/http/configuration"
> + xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
> + xmlns:jaxws="http://cxf.apache.org/jaxws"
> + xmlns:cxf="http://cxf.apache.org/core"
> + xsi:schemaLocation="
> + http://cxf.apache.org/configuration/security
> + http://cxf.apache.org/schemas/configuration/security.xsd
> + http://cxf.apache.org/transports/http/configuration
> + http://cxf.apache.org/schemas/configuration/http-conf.xsd
> + http://cxf.apache.org/transports/http-jetty/configuration
> + http://cxf.apache.org/schemas/configuration/http-jetty.xsd
> + http://cxf.apache.org/jaxws
> + http://cxf.apache.org/schemas/jaxws.xsd
> + http://www.springframework.org/schema/beans
> + http://www.springframework.org/schema/beans/spring-beans.xsd
> + http://cxf.apache.org/core
> + http://cxf.apache.org/schemas/core.xsd">
> +
> + <cxf:bus bus="cxf">
> + <cxf:properties>
> + <entry key="bus.jmx.enabled" value="true"/>
> + <entry key="bus.jmx.JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi" />
> + </cxf:properties>
> + </cxf:bus>
> +</beans>
>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: git commit: [CXF-5661]add more JMX operations for ManagedEndpoint
mbean
Posted by Sergey Beryozkin <sb...@gmail.com>.
On 01/04/14 10:46, Sergey Beryozkin wrote:
> Hi Freeman
>
> IMHO it appears to be a rather 'intrusive' commit. I'm sure it will help
> with the JMX improvements work somehow but here are some comments:
>
> Here are some comments:
> - should your bean annotation introspectors to do with JMX be moved to
> rt/management, do they belong to the core ? All these Jackson deps just
> hit the eye :-), nothing against Jackson here per se, just seems it is
> not in the right place
Yeah, ManagedEndpoint is in the core - may be it can be migrated into
rt/management in 3.0 ?
Cheers, Sergey
> - AbstractJAXRSFactoryBean update: I don't think we need to keep the
> custom classes map within every created endpoint by default for the sake
> of the optional JMX improvement: if you need it for the JMX work then
> lets consider how this can be optionally done, example, add a service
> endpoint listener and add the classes map from there, etc, so lets
> remove those lines for now
>
> Thanks, Sergey
>