modules/enterprise/server/jar/pom.xml | 107 +++++---- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java | 109 ++++++---- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java | 62 ++++- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java | 6 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertConditionRest.java | 10 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertDefinitionRest.java | 7 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertNotificationRest.java | 4 modules/enterprise/server/jar/src/main/xsl/apiout2docbook.xsl | 22 +- modules/helpers/rest-docs-generator/pom.xml | 9 modules/helpers/rest-docs-generator/src/main/java/org/rhq/helpers/rest_docs_generator/ClassLevelProcessor.java | 37 ++- 10 files changed, 246 insertions(+), 127 deletions(-)
New commits: commit ffc824545987d3a3ec959b82208f79c933c2ae41 Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Jan 29 14:23:16 2013 -0500
Even more MergeInventoryReport speed - avoid slsb call overhead by performing relevant query locally - remove unnecessary em.find - convert some em.find calls to em.getReference
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java index 29ea65c..cea1f6e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java @@ -37,6 +37,7 @@ import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.persistence.EntityManager; +import javax.persistence.NoResultException; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.security.auth.login.LoginException; @@ -866,7 +867,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot log.debug("Agent claims resource is already in inventory. Id=" + resource.getId()); }
- existingResource = entityManager.find(Resource.class, resource.getId()); + existingResource = entityManager.getReference(Resource.class, resource.getId()); if (isDebugEnabled) { if (null != existingResource) { log.debug("Found resource already in inventory. Id=" + resource.getId()); @@ -893,7 +894,6 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot // relocate the parent. Anyway, I'm not going to touch it even though it slows things down. ResourceType resourceType = resource.getResourceType(); Resource parent = resource; - Subject overlord = subjectManager.getOverlord();
while (null != parent && null == existingResource) { parent = parent.getParentResource(); @@ -914,7 +914,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot }
if (null == existingParent) { - existingParent = entityManager.find(Resource.class, parentId); + existingParent = entityManager.getReference(Resource.class, parentId); if (null != existingParent) { if (null != parentMap) { parentMap.put(parentId, existingParent); @@ -928,8 +928,16 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
// We found the parent in inventory, so now see if we can find this resource in inventory by using // the parent, the resource key (unique among siblings), the plugin and the type. - existingResource = resourceManager.getResourceByParentAndKey(overlord, existingParent, - resource.getResourceKey(), resourceType.getPlugin(), resourceType.getName()); + Query query = entityManager.createNamedQuery(Resource.QUERY_FIND_BY_PARENT_AND_KEY); + query.setParameter("parent", existingParent); + query.setParameter("key", resource.getResourceKey()); + query.setParameter("plugin", resourceType.getPlugin()); + query.setParameter("typeName", resourceType.getName()); + try { + existingResource = (Resource) query.getSingleResult(); + } catch (NoResultException e) { + existingResource = null; + } }
if (null != existingResource) { @@ -957,6 +965,12 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot return existingResource; }
+ /** + * <p>Requires A Transaction.</p> + * @param updatedResource pojo + * @param existingResource attached entity + * @throws InvalidInventoryReportException + */ private void updateExistingResource(Resource updatedResource, Resource existingResource) throws InvalidInventoryReportException { /* @@ -974,9 +988,6 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot return; }
- // get an attached entity to update - existingResource = entityManager.find(Resource.class, existingResource.getId()); - Resource existingParent = existingResource.getParentResource(); Resource updatedParent = updatedResource.getParentResource(); ResourceType existingResourceParentType = (existingParent != null) ? existingResource.getParentResource()
commit 16a2dc05205e491850e747368627ec54bdfdbedd Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Jan 29 11:36:46 2013 -0500
More mergeInventoryReport speed - add map cache of attached parent entities to avoid redundant DB fetches - replace named query fetch with simple em.find where possible - trivial, rename some private methods that were named inappropriately
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java index 7a5d024..29ea65c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java @@ -37,7 +37,6 @@ import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.persistence.EntityManager; -import javax.persistence.NoResultException; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.security.auth.login.LoginException; @@ -509,7 +508,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot + resource.getResourceType()); }
- Resource existingResource = findExistingResource(resource); + Resource existingResource = findExistingResource(resource, null); if (existingResource != null) { mergeResourceResponse = new MergeResourceResponse(existingResource.getId(), true); } else { @@ -791,20 +790,22 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
long batchStart = System.currentTimeMillis(); boolean isDebugEnabled = log.isDebugEnabled(); + // Cache parent resources we've already fetched from the DB, many resources will have the same parent + Map<Integer, Resource> parentMap = new HashMap<Integer, Resource>();
for (Resource resource : resourceBatch) { Resource existingResource = null; long start = System.currentTimeMillis();
- existingResource = findExistingResource(resource); + existingResource = findExistingResource(resource, parentMap);
// Does this resource already exist in inventory? If so, update, otherwise add if (null != existingResource) { - updateExistingResourceInNewTransaction(resource, existingResource); + updateExistingResource(resource, existingResource);
} else { presetAgent(resource, agent); - persistResourceInNewTransaction(resource); + persistResource(resource, parentMap); }
if (isDebugEnabled) { @@ -813,6 +814,9 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot } }
+ // Help out the GC + parentMap.clear(); + if (isDebugEnabled) { long delta = (System.currentTimeMillis() - batchStart); log.debug("Resource Batch merged: size/average/millis=" + resourceBatch.size() + "/" + delta @@ -834,15 +838,19 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot }
/** + * <p>Requires A Transaction</p> + * * Given a resource, will attempt to find it in the server's inventory (that is, finds it in the database). If the * given resource's ID does not exist in the database, it will be looked up by its resource key. If the resource * cannot be found either via ID or resource key then SIDE EFFECT: the given resource's ID will be reset to 0 and null * will be returned. * - * @param resource Pojo containing resourceId, key, and parentResoure (if applicable) + * @param resource Pojo containing resourceId, key, and parentResoure (if applicable) + * @param parentMap, if supplied, holds previously fetched parent pojos. useful when the calling code does many + * finds for a few parents. If not found in the map the db will be searched, the map will be updated if possible. * @return the Resource entity found in the database and matching the given resource. */ - private Resource findExistingResource(Resource resource) { + private Resource findExistingResource(Resource resource, Map<Integer, Resource> parentMap) {
boolean isDebugEnabled = log.isDebugEnabled();
@@ -850,27 +858,20 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot log.debug("getExistingResource processing for [" + resource + "]"); }
- // We perform this query a lot during a large inventory merge, so minimize overhead by using it directly - Query query = entityManager.createNamedQuery(Resource.QUERY_FIND_BY_ID); + // We perform this query a lot during a large inventory merge, so minimize overhead by using it directly Resource existingResource = null; - Subject overlord = subjectManager.getOverlord();
if (resource.getId() != 0) { if (isDebugEnabled) { log.debug("Agent claims resource is already in inventory. Id=" + resource.getId()); }
- try { - query.setParameter("resourceId", resource.getId()); - existingResource = (Resource) query.getSingleResult(); - if (isDebugEnabled) { + existingResource = entityManager.find(Resource.class, resource.getId()); + if (isDebugEnabled) { + if (null != existingResource) { log.debug("Found resource already in inventory. Id=" + resource.getId()); - } - } catch (NoResultException e) { - existingResource = null; - - // agent lied - agent's copy of JON server inventory must be stale. - if (isDebugEnabled) { + } else { + // agent lied - agent's copy of JON server inventory must be stale. log.debug("However, no resource exists with the specified id. Id=" + resource.getId()); } } @@ -892,6 +893,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot // relocate the parent. Anyway, I'm not going to touch it even though it slows things down. ResourceType resourceType = resource.getResourceType(); Resource parent = resource; + Subject overlord = subjectManager.getOverlord();
while (null != parent && null == existingResource) { parent = parent.getParentResource(); @@ -899,18 +901,28 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot // check if the parent is in inventory. This might not be the case during initial sync-up for resource upgrade. Resource existingParent = null; if (null != parent) { - if (parent.getId() <= 0) { + int parentId = parent.getId(); + + if (parentId <= 0) { log.warn("Expected potential parent resource to have a valid ID. Parent=" + parent + ", Child=" + resource); }
- try { - query.setParameter("resourceId", parent.getId()); - existingParent = (Resource) query.getSingleResult(); + // See if we already fetched this parent and it's in our cache map, if so, use it. + if (null != parentMap) { + existingParent = parentMap.get(parentId); + }
- } catch (NoResultException e) { - // this parent is not known to the server, so there's no point in trying to find a child of it... - continue; + if (null == existingParent) { + existingParent = entityManager.find(Resource.class, parentId); + if (null != existingParent) { + if (null != parentMap) { + parentMap.put(parentId, existingParent); + } + } else { + // this parent is not known to the server, so there's no point in trying to find a child of it... + continue; + } } }
@@ -945,7 +957,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot return existingResource; }
- private void updateExistingResourceInNewTransaction(Resource updatedResource, Resource existingResource) + private void updateExistingResource(Resource updatedResource, Resource existingResource) throws InvalidInventoryReportException { /* * there exists a small window of time after the synchronous part of the uninventory and before the async @@ -1088,13 +1100,25 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot return true; }
- private void persistResourceInNewTransaction(Resource resource) { + private void persistResource(Resource resource, Map<Integer, Resource> parentMap) {
- Resource parentResource = resource.getParentResource(); + // Id of detached parent resource + Integer parentId = (null != resource.getParentResource()) ? resource.getParentResource().getId() : null;
- if (null != parentResource) { - // Find the parent resource entity and create the parent-child relationship - parentResource = findExistingResource(parentResource); + // attached parentResource + Resource parentResource = null; + + if (null != parentId) { + // look in our map cache first + if (null != parentMap) { + parentResource = parentMap.get(parentId); + } + // if not in cache, try the DB + if (null == parentResource) { + // Find the parent resource entity + parentResource = entityManager.find(Resource.class, parentId); + } + // if the parent exists, create the parent-child relationship if (null != parentResource) { parentResource.addChildResource(resource); }
commit 6c6b3984c01f54c98c2c19536410af8704063108 Author: Heiko W. Rupp hwr@redhat.com Date: Tue Jan 29 17:16:41 2013 +0100
Improve representation of types.
diff --git a/modules/helpers/rest-docs-generator/src/main/java/org/rhq/helpers/rest_docs_generator/ClassLevelProcessor.java b/modules/helpers/rest-docs-generator/src/main/java/org/rhq/helpers/rest_docs_generator/ClassLevelProcessor.java index cb1a56e..72be1ed 100644 --- a/modules/helpers/rest-docs-generator/src/main/java/org/rhq/helpers/rest_docs_generator/ClassLevelProcessor.java +++ b/modules/helpers/rest-docs-generator/src/main/java/org/rhq/helpers/rest_docs_generator/ClassLevelProcessor.java @@ -328,8 +328,11 @@ public class ClassLevelProcessor extends AbstractProcessor { } if (typeString.contains(modelPackage)) { String mps = modelPackage.endsWith(".") ? modelPackage : modelPackage + "."; + // For a generic collection we need to find the "inner type" and link to it + int offset = typeString.contains("<") ? typeString.indexOf('<') +1 : 0; + String restType = typeString.substring(offset + modelPackage.length()+1); typeString = typeString.replace(mps,""); - typeId = "..." + typeString; // TODO in case of Collection<TypeString> only take the part from the modelPackage + typeId = "..." + restType; } element.setAttribute("type", typeString); element.setAttribute("typeId", typeId); @@ -380,7 +383,7 @@ public class ClassLevelProcessor extends AbstractProcessor {
Element elem = doc.createElement("data"); xmlRoot.appendChild(elem); - elem.setAttribute("name",classElementIn.getSimpleName().toString()); + elem.setAttribute("name", classElementIn.getSimpleName().toString()); elem.setAttribute("nameId","..." + classElementIn.getSimpleName().toString()); ApiClass api = classElementIn.getAnnotation(ApiClass.class); if (api!=null) { @@ -427,13 +430,15 @@ public class ClassLevelProcessor extends AbstractProcessor { TypeMirror returnTypeMirror = m.getReturnType(); // for types in the modelPackage or java.lang, remove the fqdn String typeName = returnTypeMirror.toString(); - if (typeName.startsWith(modelPackage)) { - typeName = typeName.substring(modelPackage.length()+1); + if (typeName.contains(modelPackage)) { + typeName = typeName.replace(modelPackage+".",""); } - else if (typeName.startsWith("java.lang")) { - typeName = typeName.substring("java.lang".length()+1); + if (typeName.contains("java.lang.")) { + typeName = typeName.replaceAll("java\.lang\.", ""); + } + if (typeName.contains("java.util.")) { + typeName = typeName.replaceAll("java\.util\.",""); } - // TODO for collection<type> remove the collection expression and set some collection attribute mElem.setAttribute("type", typeName); } }
commit 4fa01930008ddf35ff9956c7c8a0ad9fb9ef72d4 Author: Heiko W. Rupp hwr@redhat.com Date: Tue Jan 29 11:19:31 2013 +0100
Improve documentation and get the processor to work again. Generate links from parameters to domain classes, upgrade the docbook plugin.
diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml index 3b9f92d..7aef625 100644 --- a/modules/enterprise/server/jar/pom.xml +++ b/modules/enterprise/server/jar/pom.xml @@ -22,7 +22,7 @@ </properties>
<dependencies> - + <!-- Internal Deps -->
<!-- rhq-enterprise-comm pulls in the old version of jboss remoting. The old version of remoting @@ -35,7 +35,7 @@ <dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> - <version>3.1.0.GA</version> + <version>${jboss-logging.version}</version> <scope>test</scope> </dependency> <dependency> @@ -86,7 +86,7 @@ <artifactId>rhq-common-drift</artifactId> <version>${project.version}</version> </dependency> - + <dependency> <groupId>com.googlecode.java-diff-utils</groupId> <artifactId>diffutils</artifactId> @@ -115,7 +115,7 @@
<!-- Note, the test deps are intentionally placed above the other scoped deps because of classpath reasons. Maven orders the [test] classpath in the order listed in the pom. --> - +
<dependency> <groupId>org.jboss.spec</groupId> @@ -124,7 +124,7 @@ <scope>provided</scope> <type>pom</type> </dependency> - + <dependency> <groupId>org.rhq</groupId> <artifactId>test-utils</artifactId> @@ -137,7 +137,7 @@ </exclusion> </exclusions> </dependency> - + <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-core-domain</artifactId> @@ -145,15 +145,15 @@ <type>test-jar</type> <scope>test</scope> </dependency> - - + + <!-- 3rd Party Deps -->
- <!-- do we really need this version, for now use the version provided by AS7, declare just below --> + <!-- do we really need this version, for now use the version provided by AS7, declare just below --> <dependency> <groupId>org.antlr</groupId> <artifactId>antlr-runtime</artifactId> - <version>3.2</version> + <version>3.2</version> <exclusions> <exclusion> <groupId>antlr</groupId> @@ -162,13 +162,13 @@ <exclusion> <groupId>org.antlr</groupId> <artifactId>antlr</artifactId> - </exclusion> - </exclusions> - </dependency> + </exclusion> + </exclusions> + </dependency>
<dependency> <groupId>antlr</groupId> - <artifactId>antlr</artifactId> + <artifactId>antlr</artifactId> <scope>provided</scope> </dependency>
@@ -217,7 +217,7 @@ <groupId>gnu-getopt</groupId> <artifactId>getopt</artifactId> </dependency> - + <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> @@ -226,7 +226,7 @@
<dependency> <groupId>jboss</groupId> - <artifactId>jboss-cache</artifactId> + <artifactId>jboss-cache</artifactId> <scope>compile</scope> </dependency>
@@ -236,13 +236,13 @@ <scope>provided</scope> </dependency>
- <!-- JBoss annotations like @TransactionTimeout --> + <!-- JBoss annotations like @TransactionTimeout --> <dependency> <groupId>org.jboss.ejb3</groupId> <artifactId>jboss-ejb3-ext-api</artifactId> <scope>provided</scope> </dependency> - + <!-- annotations like @ExcludeDefaultInterceptors --> <dependency> <groupId>org.jboss.spec.javax.interceptor</groupId> @@ -268,7 +268,7 @@ <artifactId>jboss-ejb-api_3.1_spec</artifactId> <scope>provided</scope> </dependency> - + <dependency> <groupId>org.jboss.spec.javax.jms</groupId> <artifactId>jboss-jms-api_1.1_spec</artifactId> @@ -402,7 +402,7 @@ <artifactId>snakeyaml</artifactId> <version>1.8</version> </dependency> - + <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> @@ -424,6 +424,13 @@ <scope>test</scope> </dependency>
+ <dependency> + <groupId>org.rhq.helpers</groupId> + <artifactId>rest-docs-generator</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + </dependencies>
<build> @@ -836,26 +843,37 @@ <groupId>org.rhq.helpers</groupId> <artifactId>rest-docs-generator</artifactId> <version>${project.version}</version> - <scope>provided</scope> </dependency> + + <!-- We need this, as otherwise processing fails completely with a class not found exception --> + <dependency> + <groupId>org.jboss.logging</groupId> + <artifactId>jboss-logging</artifactId> + <version>${jboss-logging.version}</version> + </dependency> + </dependencies>
<build> <!-- Document generation from the Annotations on the REST-API. --> - <!-- TODO move to a better suited processing phase --> <plugins> - <plugin> - <groupId>org.bsc.maven</groupId> - <artifactId>maven-processor-plugin</artifactId> - <version>2.0.6-redhat</version> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.0</version> <configuration> - <processors> + <annotationProcessors> <processor>org.rhq.helpers.rest_docs_generator.ClassLevelProcessor</processor> - </processors> - <compilerArguments>-AtargetDirectory=${project.build.directory}/docs/xml</compilerArguments> - <!-- Comment the next line in to get more verbose output for debugging --> - <!--<compilerArguments>-Averbose=true</compilerArguments> --> + </annotationProcessors> + <proc>only</proc> + <compilerArguments> + <AtargetDirectory>${project.build.directory}/docs/xml</AtargetDirectory> + <AmodelPkg>org.rhq.enterprise.server.rest.domain</AmodelPkg> + <!-- enable the next line to have the output of the processor shown on console --> + <!--<Averbose>true</Averbose>--> + </compilerArguments> + <!-- set the next to true to enable verbose output of the compiler plugin; default from the evn is true, but this is too noisy --> + <verbose>false</verbose> </configuration> <executions> <execution> @@ -863,20 +881,11 @@ <phase>process-classes</phase> <goals> <!-- We want to process the classes in src/ --> - <goal>process</goal> + <goal>compile</goal> </goals> </execution> </executions> </plugin> - - <!-- Disable annotation processors during normal compilation --> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <compilerArgument>-proc:none</compilerArgument> - </configuration> - </plugin>
<plugin> <groupId>org.codehaus.mojo</groupId> @@ -892,6 +901,7 @@ <configuration> <transformationSets> <transformationSet> + <!-- Generate a html rendering --> <!-- org.rhq.helpers.rest_docs_generator.test plugin wrote to target/docs/xml (see -AtargetDirectory above) --> <dir>target/docs/xml</dir> <includes> @@ -901,7 +911,7 @@ <parameters> <parameter> <name>basePath</name> - <value>http://localhost:7080/rest/1</value> + <value>http://localhost:7080/rest</value> </parameter> </parameters> <outputDir>${project.build.directory}/docs/html</outputDir> @@ -912,6 +922,7 @@ </fileMappers> </transformationSet> <transformationSet> + <!-- Generate a docbook file as input to fop --> <!-- org.rhq.helpers.rest_docs_generator.test plugin wrote to target/docs/xml (see -AtargetDirectory above) --> <dir>target/docs/xml</dir> <includes> @@ -921,7 +932,7 @@ <parameters> <parameter> <name>basePath</name> - <value>http://localhost:7080/rest/1</value> + <value>http://localhost:7080/rest</value> </parameter> </parameters> <outputDir>${project.build.directory}/docs/xml</outputDir> @@ -934,11 +945,11 @@ </transformationSets> </configuration> </plugin> - + <plugin> <groupId>com.agilejava.docbkx</groupId> <artifactId>docbkx-maven-plugin</artifactId> - <version>2.0.9</version> + <version>2.0.14</version> <executions> <execution> <phase>process-classes</phase> @@ -951,14 +962,14 @@ <configuration> <sourceDirectory>target/docs/xml</sourceDirectory> <!-- from previous plugin, 2nd transformation set --> <includes>rest-api-out.dbx.xml</includes> - <hyphenate>false</hyphenate> + <hyphenate>true</hyphenate> <generateToc>true</generateToc> </configuration> </plugin> </plugins> </build> </profile> - + <profile> <id>cobertura</id> <build> @@ -1067,7 +1078,7 @@ </plugins> </build> </profile> - + </profiles>
<reporting> diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java index d0bb88e..97200cd 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/AlertDefinitionHandlerBean.java @@ -126,6 +126,7 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
+ // Redirect from /definition to /definitions for GET requests @GET @Path("/definition") public Response redirectDefinitionToDefinitions(@Context UriInfo uriInfo) { @@ -178,11 +179,11 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@POST @Path("/definitions") - @ApiOperation("Create an AlertDefinition for the resource/group/resource type passed as query param. Only one of the three params may be given at any time.") - public Response createAlertDefinition(@QueryParam("resourceId") Integer resourceId, - @QueryParam("groupId") Integer groupId, - @QueryParam("resourceTypeId") Integer resourceTypeId, - AlertDefinitionRest adr, + @ApiOperation("Create an AlertDefinition for the resource/group/resource type passed as query param. One and only one of the three params must be given at any time.") + public Response createAlertDefinition(@ApiParam("The id of the resource to attach the definition to") @QueryParam("resourceId") Integer resourceId, + @ApiParam("The id of the group to attach the definition to") @QueryParam("groupId") Integer groupId, + @ApiParam("The id of the resource type to attach the definition to") @QueryParam("resourceTypeId") Integer resourceTypeId, + @ApiParam("The data for the new definition") AlertDefinitionRest adr, @Context UriInfo uriInfo) {
int i = 0; @@ -266,7 +267,7 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { @ApiOperation(value = "Update the alert definition (priority, enablement, dampening, recovery)", notes = "Priority must be HIGH,LOW,MEDIUM") public Response updateDefinition( @ApiParam("Id of the alert definition to update") @PathParam("id") int definitionId, - AlertDefinitionRest definitionRest) { + @ApiParam("Data for the update") AlertDefinitionRest definitionRest) {
AlertDefinition definition = alertDefinitionManager.getAlertDefinition(caller,definitionId); if (definition==null) @@ -303,14 +304,18 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { @DELETE @Path("definition/{id}") @ApiOperation("Delete an alert definition") - public Response deleteDefinition(@PathParam("id") int definitionId) { + public Response deleteDefinition(@ApiParam("Id of the definition to delete") @PathParam("id") int definitionId) {
- int count = alertDefinitionManager.removeAlertDefinitions(caller, new int[]{definitionId}); + alertDefinitionManager.removeAlertDefinitions(caller, new int[]{definitionId});
return Response.noContent().build(); }
- + /** + * Create a dampening object for the passed definition from the alert definition rest that is passed in. + * @param alertDefinition The alert definition to modify + * @param adr The incoming AlertDefinitonRest object + */ private void setDampeningFromRest(AlertDefinition alertDefinition, AlertDefinitionRest adr) { AlertDampening.Category dampeningCategory; try { @@ -373,7 +378,10 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@POST @Path("definition/{id}/conditions") - public Response addConditionToDefinition(@PathParam("id") int definitionId, AlertConditionRest conditionRest, @Context UriInfo uriInfo) { + @ApiOperation("Add a new alert condition to an existing alert definition") + public Response addConditionToDefinition( + @ApiParam("The id of the alert definition") @PathParam("id") int definitionId, + @ApiParam("The condition to add") AlertConditionRest conditionRest, @Context UriInfo uriInfo) {
AlertDefinition definition = alertDefinitionManager.getAlertDefinition(caller,definitionId); if (definition==null) @@ -392,7 +400,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@DELETE @Path("condition/{cid}") - public Response deleteCondition(@PathParam("cid") int conditionId) { + @ApiOperation("Remove an alert condition") + public Response deleteCondition( + @ApiParam("The id of the condition to remove")@PathParam("cid") int conditionId) { Integer definitionId = findDefinitionIdForConditionId(conditionId);
AlertDefinition definition2 = entityManager.find(AlertDefinition.class,definitionId); @@ -427,7 +437,10 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@PUT @Path("condition/{cid}") - public Response updateCondition(@PathParam("cid") int conditionId, AlertConditionRest conditionRest, @Context UriInfo uriInfo) { + @ApiOperation("Update an existing condition of an alert definition.Note that the update will change the id of the condition") + public Response updateCondition( + @ApiParam("The id of the condition to update") @PathParam("cid") int conditionId, + @ApiParam("The updated condition") AlertConditionRest conditionRest, @Context UriInfo uriInfo) {
Integer definitionId = findDefinitionIdForConditionId(conditionId);
@@ -465,7 +478,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@GET @Path("condition/{cid}") - public Response getCondition(@PathParam("cid") int conditionId) { + @ApiOperation("Retrieve a condition of an alert definition by its condition id") + public Response getCondition( + @ApiParam("The id of the condition to retrieve") @PathParam("cid") int conditionId) {
AlertCondition condition = conditionMgr.getAlertConditionById(conditionId); AlertConditionRest acr = conditionToConditionRest(condition); @@ -521,7 +536,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@GET @Path("notification/{nid}") - public Response getNotification(@PathParam("nid") int notificationId) { + @ApiOperation("Return a notification definition by its id") + public Response getNotification( + @ApiParam("The id of the notification definition to retrieve") @PathParam("nid") int notificationId) {
AlertNotification notification = notificationMgr.getAlertNotification(caller,notificationId); AlertNotificationRest anr = notificationToNotificationRest(notification); @@ -531,7 +548,9 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@DELETE @Path("notification/{nid}") - public Response deleteNotification(@PathParam("nid") int notificationId) { + @ApiOperation("Remove a notification definition") + public Response deleteNotification( + @ApiParam("The id of the notification definition to remove") @PathParam("nid") int notificationId) {
AlertNotification notification = notificationMgr.getAlertNotification(caller,notificationId); AlertDefinition definition = alertDefinitionManager.getAlertDefinition(caller,notification.getAlertDefinition().getId()); @@ -548,7 +567,10 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@PUT @Path("notification/{nid}") - public Response updateNotification(@PathParam("nid") int notificationId, AlertNotificationRest notificationRest) { + @ApiOperation("Update a notification definition") + public Response updateNotification( + @ApiParam("The id of the notification definition to update") @PathParam("nid") int notificationId, + @ApiParam("The updated notification definition to use") AlertNotificationRest notificationRest) {
AlertNotification notification = notificationMgr.getAlertNotification(caller,notificationId); AlertDefinition definition = alertDefinitionManager.getAlertDefinition(caller,notification.getAlertDefinition().getId()); @@ -578,7 +600,10 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean {
@POST @Path("definition/{id}/notifications") - public Response addNotificationToDefinition(@PathParam("id") int definitionId, AlertNotificationRest notificationRest, @Context UriInfo uriInfo) { + @ApiOperation("Add a new notification definition to an alert definition") + public Response addNotificationToDefinition( + @ApiParam("Id of the alert definition that should get the notification definition") @PathParam("id") int definitionId, + @ApiParam("The notification definition to add") AlertNotificationRest notificationRest, @Context UriInfo uriInfo) {
AlertNotification notification = new AlertNotification(notificationRest.getSenderName());
@@ -670,7 +695,8 @@ public class AlertDefinitionHandlerBean extends AbstractRestBean { @ApiOperation("Return an alert notification sender by name. This includes information about the configuration it expects") @GET @GZIP @Path("sender/{name}") - public Response getAlertSenderByName(@PathParam("name")String senderName, @Context UriInfo uriInfo) { + public Response getAlertSenderByName( + @ApiParam("Name of the sender to retrieve") @PathParam("name")String senderName, @Context UriInfo uriInfo) {
AlertSenderInfo info = notificationMgr.getAlertInfoForSender(senderName); if (info==null) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java index 7998294..e2abffd 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/RootHandlerBean.java @@ -35,6 +35,9 @@ import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo;
+import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; + import org.rhq.enterprise.server.rest.domain.Link;
/** @@ -42,6 +45,7 @@ import org.rhq.enterprise.server.rest.domain.Link; * * @author Heiko W. Rupp */ +@Api("Handle the root context to have an anchor for discoverability") @Path("/") @Interceptors(SetCallerInterceptor.class) @Stateless @@ -60,12 +64,14 @@ public class RootHandlerBean extends AbstractRestBean {
@GET @Path("index") + @ApiOperation("Return links from the root /index of the REST-resource tree") public Response index(@Context Request request, @Context HttpHeaders headers, @Context UriInfo uriInfo) { return handleIndex(headers,uriInfo); }
@GET @Path("/") + @ApiOperation("Return links from the root / of the REST-resource tree") public Response index2(@Context Request request, @Context HttpHeaders headers, @Context UriInfo uriInfo) { return handleIndex(headers,uriInfo); } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertConditionRest.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertConditionRest.java index 890a3fe..1ada16c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertConditionRest.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertConditionRest.java @@ -21,6 +21,9 @@ package org.rhq.enterprise.server.rest.domain;
import javax.xml.bind.annotation.XmlRootElement;
+import com.wordnik.swagger.annotations.ApiClass; +import com.wordnik.swagger.annotations.ApiProperty; + import org.rhq.core.domain.alert.AlertConditionCategory; import org.rhq.core.domain.alert.AlertConditionOperator;
@@ -29,6 +32,7 @@ import org.rhq.core.domain.alert.AlertConditionOperator; * An alert definition can have any number of definitions * @author Heiko W. Rupp */ +@ApiClass(value = "One condition for an alert definition") @XmlRootElement(name = "condition") public class AlertConditionRest {
@@ -44,6 +48,7 @@ public class AlertConditionRest { public AlertConditionRest() { }
+ @ApiProperty("Comparator to use with this definition") public AlertConditionOperator getName() { return name; } @@ -52,6 +57,7 @@ public class AlertConditionRest { this.name = name; }
+ @ApiProperty("The category") public AlertConditionCategory getCategory() { return category; } @@ -64,10 +70,12 @@ public class AlertConditionRest { this.id = id; }
+ @ApiProperty("Id of the condition.Note that this is not stable - when you update the condition, its id will change") public int getId() { return id; }
+ @ApiProperty("THe threshold to compare against") public Double getThreshold() { return threshold; } @@ -76,6 +84,7 @@ public class AlertConditionRest { this.threshold = threshold; }
+ @ApiProperty("Options to this condition. Depends on the category used") public String getOption() { return option; } @@ -100,6 +109,7 @@ public class AlertConditionRest { this.comparator = comparator; }
+ @ApiProperty("The id of the measurement definition, this comparator should apply to. A metric schedule can be identified by a resource id and a definition id.") public int getMeasurementDefinition() { return measurementDefinition; } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertDefinitionRest.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertDefinitionRest.java index 0e6b351..cecd946 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertDefinitionRest.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertDefinitionRest.java @@ -26,8 +26,6 @@ import javax.xml.bind.annotation.XmlRootElement; import com.wordnik.swagger.annotations.ApiClass; import com.wordnik.swagger.annotations.ApiProperty;
-import org.rhq.core.domain.alert.AlertDampening; - /** * Alert Definition * @author Heiko W. Rupp @@ -48,6 +46,7 @@ public class AlertDefinitionRest { String dampeningCount; String dampeningPeriod;
+ @SuppressWarnings("unused") public AlertDefinitionRest() { }
@@ -92,6 +91,7 @@ public class AlertDefinitionRest { this.priority = priority; }
+ @ApiProperty(value = "Id of an alert definition to recover") public int getRecoveryId() { return recoveryId; } @@ -128,6 +128,7 @@ public class AlertDefinitionRest { this.notifications = notifications; }
+ @ApiProperty(value = "Category for dampening. ONCE means 'disable definition after firing'", allowableValues = "NONE, CONSECUTIVE_COUNT, PARTIAL_COUNT, INVERSE_COUNT, DURATION_COUNT, NO_DUPLICATES, ONCE") public String getDampeningCategory() { return dampeningCategory; } @@ -136,6 +137,7 @@ public class AlertDefinitionRest { this.dampeningCategory = dampeningCategory; }
+ @ApiProperty(value = "Number of occurrences of an alert (in a given period)") public String getDampeningCount() { return dampeningCount; } @@ -144,6 +146,7 @@ public class AlertDefinitionRest { this.dampeningCount = dampeningCount; }
+ @ApiProperty( value = "Period to check events. Only applicable for PARTIAL_COUNT, DURATION_COUNT, INVERSE_COUNT") public String getDampeningPeriod() { return dampeningPeriod; } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertNotificationRest.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertNotificationRest.java index 1b6a46b..c4cd0c5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertNotificationRest.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/domain/AlertNotificationRest.java @@ -31,7 +31,7 @@ import com.wordnik.swagger.annotations.ApiProperty; * Representation of notifications * @author Heiko W. Rupp */ -@ApiClass("Represents an alert notification") +@ApiClass("Represents an alert notification definition") @XmlRootElement(name = "notification") public class AlertNotificationRest {
@@ -42,6 +42,7 @@ public class AlertNotificationRest { public AlertNotificationRest() { }
+ @ApiProperty("Id of the definition. This will change if the notification is updated.") public int getId() { return id; } @@ -59,6 +60,7 @@ public class AlertNotificationRest { this.senderName = senderName; }
+ @ApiProperty("Configuration that needs to be passed to the definition.") public Map<String, Object> getConfig() { return config; } diff --git a/modules/enterprise/server/jar/src/main/xsl/apiout2docbook.xsl b/modules/enterprise/server/jar/src/main/xsl/apiout2docbook.xsl index 97e0598..512a8d4 100644 --- a/modules/enterprise/server/jar/src/main/xsl/apiout2docbook.xsl +++ b/modules/enterprise/server/jar/src/main/xsl/apiout2docbook.xsl @@ -40,7 +40,7 @@ <xsl:element name="tocentry"> <link> <xsl:attribute name="linkend"> - <xsl:value-of select="@path"/> + <xsl:value-of select="generate-id(@path)"/> </xsl:attribute> <xsl:if test="@basePath"> <xsl:value-of select="@basePath"/> @@ -63,7 +63,7 @@ <xsl:template match="class"> <xsl:element name="section"> <xsl:attribute name="xml:id"> - <xsl:value-of select="@path"/> + <xsl:value-of select="generate-id(@path)"/> </xsl:attribute> <title> <!--/<xsl:value-of select="@path"/>--> @@ -167,7 +167,20 @@ <xsl:value-of select="@required"/> </td> <td> - <xsl:value-of select="@type"/> + xsl:choose + + <xsl:when test="starts-with(@typeId,'...')"> + <link> + <xsl:attribute name="linkend"> + <xsl:value-of select="@typeId"/> + </xsl:attribute> + <xsl:value-of select="@type"/> + </link> + </xsl:when> + xsl:otherwise + <xsl:value-of select="@type"/> + </xsl:otherwise> + </xsl:choose> </td> <td> xsl:choose @@ -233,6 +246,9 @@
<xsl:template match="data"> <xsl:element name="section"> + <xsl:attribute name="xml:id"> + <xsl:value-of select="@nameId"/> + </xsl:attribute> <title>Data-Class: <xsl:value-of select="@name"/></title> <xsl:if test="@abstract"> <subtitle><xsl:value-of select="@abstract"/></subtitle> diff --git a/modules/helpers/rest-docs-generator/pom.xml b/modules/helpers/rest-docs-generator/pom.xml index af3374f..f97d2de 100644 --- a/modules/helpers/rest-docs-generator/pom.xml +++ b/modules/helpers/rest-docs-generator/pom.xml @@ -48,15 +48,6 @@ </testResources> <plugins>
-<!-- - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>animal-sniffer-maven-plugin</artifactId> - <configuration> - <skip>true</skip> - </configuration> - </plugin> ---> <plugin> <groupId>org.bsc.maven</groupId> <artifactId>maven-processor-plugin</artifactId> diff --git a/modules/helpers/rest-docs-generator/src/main/java/org/rhq/helpers/rest_docs_generator/ClassLevelProcessor.java b/modules/helpers/rest-docs-generator/src/main/java/org/rhq/helpers/rest_docs_generator/ClassLevelProcessor.java index c10dd62..cb1a56e 100644 --- a/modules/helpers/rest-docs-generator/src/main/java/org/rhq/helpers/rest_docs_generator/ClassLevelProcessor.java +++ b/modules/helpers/rest-docs-generator/src/main/java/org/rhq/helpers/rest_docs_generator/ClassLevelProcessor.java @@ -58,7 +58,7 @@ import org.jboss.resteasy.annotations.GZIP; */
@SupportedOptions({ClassLevelProcessor.TARGET_DIRECTORY,ClassLevelProcessor.VERBOSE,ClassLevelProcessor.MODEL_PACKAGE_KEY}) -@SupportedSourceVersion(SourceVersion.RELEASE_6) +@SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes(value = {"com.wordnik.swagger.annotations.*","javax.ws.rs.*","javax.xml.bind.annotation.XmlRootElement"}) public class ClassLevelProcessor extends AbstractProcessor {
@@ -318,8 +318,21 @@ public class ClassLevelProcessor extends AbstractProcessor { if (defaultValue!=null) element.setAttribute("defaultValue",defaultValue);
- - element.setAttribute("type", t.toString()); + String typeString = t.toString(); + String typeId = typeString; + if (typeString.contains("java.lang.")) { + typeString = typeString.replaceAll("java\.lang\.",""); + } + else if (typeString.contains("java.util.")) { + typeString = typeString.replaceAll("java\.util\.",""); + } + if (typeString.contains(modelPackage)) { + String mps = modelPackage.endsWith(".") ? modelPackage : modelPackage + "."; + typeString = typeString.replace(mps,""); + typeId = "..." + typeString; // TODO in case of Collection<TypeString> only take the part from the modelPackage + } + element.setAttribute("type", typeString); + element.setAttribute("typeId", typeId); } }
@@ -368,6 +381,7 @@ public class ClassLevelProcessor extends AbstractProcessor { Element elem = doc.createElement("data"); xmlRoot.appendChild(elem); elem.setAttribute("name",classElementIn.getSimpleName().toString()); + elem.setAttribute("nameId","..." + classElementIn.getSimpleName().toString()); ApiClass api = classElementIn.getAnnotation(ApiClass.class); if (api!=null) { elem.setAttribute("abstract",api.value());
rhq-commits@lists.fedorahosted.org