You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2014/09/21 14:02:04 UTC
[3/5] git commit: CAMEL-7792 JIRA component
CAMEL-7792 JIRA component
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/f261f610
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/f261f610
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/f261f610
Branch: refs/heads/master
Commit: f261f610ddf4f7b2abc472d455d01caa8413cb00
Parents: 882857f
Author: Brett Meyer <br...@3riverdev.com>
Authored: Wed Sep 17 14:24:47 2014 -0400
Committer: Willem Jiang <wi...@gmail.com>
Committed: Sun Sep 21 20:01:36 2014 +0800
----------------------------------------------------------------------
components/camel-jira/pom.xml | 74 +++++++++++
.../camel/component/jira/JIRAComponent.java | 34 +++++
.../camel/component/jira/JIRAEndpoint.java | 126 +++++++++++++++++++
.../camel/component/jira/JIRAProducer.java | 35 ++++++
.../jira/consumer/AbstractJIRAConsumer.java | 74 +++++++++++
.../component/jira/consumer/ConsumerType.java | 31 +++++
.../jira/consumer/NewCommentConsumer.java | 63 ++++++++++
.../jira/consumer/NewIssueConsumer.java | 66 ++++++++++
.../services/org/apache/camel/component/jira | 18 +++
.../src/main/resources/log4j.properties | 16 +++
components/pom.xml | 1 +
11 files changed, 538 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/camel-jira/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-jira/pom.xml b/components/camel-jira/pom.xml
new file mode 100644
index 0000000..b08f509
--- /dev/null
+++ b/components/camel-jira/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>components</artifactId>
+ <version>2.15-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-jira</artifactId>
+ <packaging>bundle</packaging>
+ <name>Camel :: JIRA</name>
+
+ <properties>
+ <camel.osgi.export.pkg>org.apache.camel.component.jira.*</camel.osgi.export.pkg>
+ <camel.osgi.export.service>org.apache.camel.spi.ComponentResolver;component=jira</camel.osgi.export.service>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.atlassian.jira</groupId>
+ <artifactId>jira-rest-java-client</artifactId>
+ <version>1.2-m01</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- testing -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- logging -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>atlassian-public</id>
+ <url>https://maven.atlassian.com/repository/public</url>
+ </repository>
+ </repositories>
+</project>
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAComponent.java b/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAComponent.java
new file mode 100644
index 0000000..022f8b5
--- /dev/null
+++ b/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAComponent.java
@@ -0,0 +1,34 @@
+/**
+ * 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.camel.component.jira;
+
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.DefaultComponent;
+
+/**
+ * Represents the component that manages {@link JIRAEndpoint}.
+ */
+public class JIRAComponent extends DefaultComponent {
+
+ protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+ Endpoint endpoint = new JIRAEndpoint(uri, this);
+ setProperties(endpoint, parameters);
+ return endpoint;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAEndpoint.java b/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAEndpoint.java
new file mode 100644
index 0000000..1aa2e2e
--- /dev/null
+++ b/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAEndpoint.java
@@ -0,0 +1,126 @@
+/**
+ * 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.camel.component.jira;
+
+import java.util.regex.Pattern;
+
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.component.jira.consumer.ConsumerType;
+import org.apache.camel.component.jira.consumer.NewCommentConsumer;
+import org.apache.camel.component.jira.consumer.NewIssueConsumer;
+import org.apache.camel.impl.DefaultEndpoint;
+
+/**
+ * The endpoint encapsulates portions of the JIRA API, relying on the jira-rest-java-client SDK.
+ * Available endpoint URIs include:
+ *
+ * CONSUMERS
+ * jira://newIssue (new tickets)
+ * jira://newComment (new comments on tickets)
+ *
+ * The endpoints will respond with jira-rest-java-client POJOs (Issue, Comment, etc.)
+ *
+ * Note: Rather than webhooks, this endpoint relies on simple polling. Reasons include:
+ * - concerned about reliability/stability if this somehow relied on an exposed, embedded server (Jetty?)
+ * - the types of payloads we're polling aren't typically large (plus, paging is available in the API)
+ * - need to support apps running somewhere not publicly accessible where a webhook would fail
+ */
+public class JIRAEndpoint extends DefaultEndpoint {
+
+ private String serverUrl = null;
+
+ private String username = null;
+
+ private String password = null;
+
+ private String jql = null;
+
+ public JIRAEndpoint(String uri, JIRAComponent component) {
+ super(uri, component);
+ }
+
+ public Producer createProducer() throws Exception {
+ return new JIRAProducer(this);
+ }
+
+ public Consumer createConsumer(Processor processor) throws Exception {
+ String uri = getEndpointUri();
+ String[] uriSplit = splitUri(getEndpointUri());
+
+ if (uriSplit.length > 0) {
+ switch (ConsumerType.fromUri(uriSplit[0])) {
+ case NEWCOMMENT:
+ return new NewCommentConsumer(this, processor);
+ case NEWISSUE:
+ return new NewIssueConsumer(this, processor);
+ default:
+ break;
+ }
+ }
+
+ throw new IllegalArgumentException("Cannot create any consumer with uri " + uri
+ + ". A consumer type was not provided (or an incorrect pairing was used).");
+ }
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+ private static String[] splitUri(String uri) {
+ Pattern p1 = Pattern.compile("jira:(//)*");
+ Pattern p2 = Pattern.compile("\\?.*");
+
+ uri = p1.matcher(uri).replaceAll("");
+ uri = p2.matcher(uri).replaceAll("");
+
+ return uri.split("/");
+ }
+
+ public String getServerUrl() {
+ return serverUrl;
+ }
+
+ public void setServerUrl(String serverUrl) {
+ this.serverUrl = serverUrl;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getJql() {
+ return jql;
+ }
+
+ public void setJql(String jql) {
+ this.jql = jql;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAProducer.java b/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAProducer.java
new file mode 100644
index 0000000..9f54bc2
--- /dev/null
+++ b/components/camel-jira/src/main/java/org/apache/camel/component/jira/JIRAProducer.java
@@ -0,0 +1,35 @@
+/**
+ * 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.camel.component.jira;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.impl.DefaultProducer;
+
+/**
+ * The Camel :: JIRA producer.
+ */
+public class JIRAProducer extends DefaultProducer {
+
+ public JIRAProducer(JIRAEndpoint endpoint) {
+ super(endpoint);
+ }
+
+ public void process(Exchange exchange) throws Exception {
+ // nothing to do, yet
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/AbstractJIRAConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/AbstractJIRAConsumer.java b/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/AbstractJIRAConsumer.java
new file mode 100644
index 0000000..90bf6d4
--- /dev/null
+++ b/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/AbstractJIRAConsumer.java
@@ -0,0 +1,74 @@
+package org.apache.camel.component.jira.consumer;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.Processor;
+import org.apache.camel.component.jira.JIRAEndpoint;
+import org.apache.camel.impl.ScheduledPollConsumer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.atlassian.jira.rest.client.JiraRestClient;
+import com.atlassian.jira.rest.client.domain.BasicIssue;
+import com.atlassian.jira.rest.client.domain.SearchResult;
+import com.atlassian.jira.rest.client.internal.jersey.JerseyJiraRestClientFactory;
+
+public abstract class AbstractJIRAConsumer extends ScheduledPollConsumer {
+
+ private static final transient Logger LOG = LoggerFactory.getLogger(AbstractJIRAConsumer.class);
+
+ private final JIRAEndpoint endpoint;
+
+ private final JiraRestClient client;
+
+ public AbstractJIRAConsumer(JIRAEndpoint endpoint, Processor processor) {
+ super(endpoint, processor);
+ this.endpoint = endpoint;
+
+ // Use a more reasonable default.
+ setDelay(6000);
+
+ final JerseyJiraRestClientFactory factory = new JerseyJiraRestClientFactory();
+ final URI jiraServerUri = URI.create(endpoint.getServerUrl());
+ client = factory.createWithBasicHttpAuthentication(
+ jiraServerUri, endpoint.getUsername(), endpoint.getPassword());
+ }
+
+ protected List<BasicIssue> getIssues() {
+ return getIssues(endpoint.getJql(), 0, 0, 500);
+ }
+
+ // Ignore maxResults if it's <= 0.
+ protected List<BasicIssue> getIssues(String jql, int start, int maxResults, int maxPerQuery) {
+ LOG.info("Indexing current JIRA issues...");
+
+ List<BasicIssue> issues = new ArrayList<BasicIssue>();
+ while ( true ) {
+ SearchResult searchResult = client.getSearchClient().searchJqlWithFullIssues(
+ jql, maxPerQuery, start, null );
+
+ for (BasicIssue issue : searchResult.getIssues()) {
+ issues.add(issue);
+ }
+
+ // Note: #getTotal == the total # the query would return *without* pagination, effectively telling us
+ // we've reached the end. Also exit early if we're limiting the # of results.
+ if ( start >= searchResult.getTotal() ||
+ (maxResults > 0 && issues.size() >= maxResults)) {
+ break;
+ }
+
+ start += maxPerQuery;
+ }
+
+ return issues;
+ }
+
+ protected JiraRestClient client() {
+ return client;
+ }
+
+ protected abstract int poll() throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/ConsumerType.java
----------------------------------------------------------------------
diff --git a/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/ConsumerType.java b/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/ConsumerType.java
new file mode 100644
index 0000000..db71d05
--- /dev/null
+++ b/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/ConsumerType.java
@@ -0,0 +1,31 @@
+/**
+ * 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.camel.component.jira.consumer;
+
+public enum ConsumerType {
+
+ NEWCOMMENT, NEWISSUE, UNKNOWN;
+
+ public static ConsumerType fromUri(String uri) {
+ for (ConsumerType consumerType : ConsumerType.values()) {
+ if (consumerType.name().equalsIgnoreCase(uri)) {
+ return consumerType;
+ }
+ }
+ return ConsumerType.UNKNOWN;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/NewCommentConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/NewCommentConsumer.java b/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/NewCommentConsumer.java
new file mode 100644
index 0000000..80e8b21
--- /dev/null
+++ b/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/NewCommentConsumer.java
@@ -0,0 +1,63 @@
+package org.apache.camel.component.jira.consumer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.component.jira.JIRAEndpoint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.atlassian.jira.rest.client.domain.BasicIssue;
+import com.atlassian.jira.rest.client.domain.Comment;
+import com.atlassian.jira.rest.client.domain.Issue;
+
+/**
+ * Consumes new comments on JIRA issues.
+ *
+ * NOTE: In your JQL, try to optimize the query as much as possible! For example, the JIRA Toolkit Plugin includes a
+// "Number of comments" custom field -- use '"Number of comments" > 0' in your query. Also try to minimize based on
+// state (status=Open), increase the polling delay, etc. We have to do a separate query for *every single* resulting
+ * ticket in order to load its comments! For large organizations, the JIRA API can be significantly slow.
+ */
+public class NewCommentConsumer extends AbstractJIRAConsumer {
+ private static final transient Logger LOG = LoggerFactory.getLogger(NewCommentConsumer.class);
+
+ private List<Long> commentIds = new ArrayList<Long>();
+
+ public NewCommentConsumer(JIRAEndpoint endpoint, Processor processor) {
+ super(endpoint, processor);
+ LOG.info("JIRA NewCommentConsumer: Indexing current issue comments...");
+ getComments();
+ }
+
+ @Override
+ protected int poll() throws Exception {
+ Stack<Comment> newComments = getComments();
+ while(!newComments.empty()) {
+ Comment newComment = newComments.pop();
+ Exchange e = getEndpoint().createExchange();
+ e.getIn().setBody(newComment);
+ getProcessor().process(e);
+ }
+ return newComments.size();
+ }
+
+ // In the end, we want *new* comments oldest to newest.
+ private Stack<Comment> getComments() {
+ Stack<Comment> newComments = new Stack<Comment>();
+ List<BasicIssue> issues = getIssues();
+ for (BasicIssue issue : issues) {
+ Issue fullIssue = client().getIssueClient().getIssue(issue.getKey(), null);
+ for (Comment comment : fullIssue.getComments()) {
+ if (!commentIds.contains(comment.getId())) {
+ newComments.push(comment);
+ commentIds.add(comment.getId());
+ }
+ }
+ }
+ return newComments;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/NewIssueConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/NewIssueConsumer.java b/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/NewIssueConsumer.java
new file mode 100644
index 0000000..a858be7
--- /dev/null
+++ b/components/camel-jira/src/main/java/org/apache/camel/component/jira/consumer/NewIssueConsumer.java
@@ -0,0 +1,66 @@
+package org.apache.camel.component.jira.consumer;
+
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.component.jira.JIRAEndpoint;
+
+import com.atlassian.jira.rest.client.domain.BasicIssue;
+
+/**
+ * Consumes new JIRA issues.
+ *
+ * NOTE: We manually add "ORDER BY key desc" to the JQL in order to optimize startup (the latest issues one at a time),
+ * rather than having to index everything.
+ */
+public class NewIssueConsumer extends AbstractJIRAConsumer {
+
+ private final String jql;
+
+ private long latestIssueId = -1;
+
+ public NewIssueConsumer(JIRAEndpoint endpoint, Processor processor) {
+ super(endpoint, processor);
+
+ jql = endpoint.getJql() + " ORDER BY key desc";
+
+ // grab only the top
+ List<BasicIssue> issues = getIssues(jql, 0, 1, 1);
+ // in case there aren't any issues...
+ if (issues.size() >= 1) {
+ latestIssueId = issues.get(0).getId();
+ }
+ }
+
+ @Override
+ protected int poll() throws Exception {
+ Stack<BasicIssue> newIssues = new Stack<BasicIssue>();
+ getNewIssues(0, newIssues);
+ while(!newIssues.empty()) {
+ BasicIssue newIssue = newIssues.pop();
+ Exchange e = getEndpoint().createExchange();
+ e.getIn().setBody(newIssue);
+ getProcessor().process(e);
+ }
+ return newIssues.size();
+ }
+
+ // In the end, we want *new* issues oldest to newest.
+ private void getNewIssues(int start, Stack<BasicIssue> stack) {
+ // grab only the top
+ List<BasicIssue> issues = getIssues(jql, start, 1, 1);
+ // in case there aren't any issues...
+ if (issues.size() >= 1) {
+ long id = issues.get(0).getId();
+ if (id > latestIssueId) {
+ stack.push(issues.get(0));
+ // try again in case multiple new issues exist
+ getNewIssues(start + 1, stack);
+ // make sure this happens now, rather than before calling #getNewIssues
+ latestIssueId = id;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/camel-jira/src/main/resources/META-INF/services/org/apache/camel/component/jira
----------------------------------------------------------------------
diff --git a/components/camel-jira/src/main/resources/META-INF/services/org/apache/camel/component/jira b/components/camel-jira/src/main/resources/META-INF/services/org/apache/camel/component/jira
new file mode 100644
index 0000000..3a73e9f
--- /dev/null
+++ b/components/camel-jira/src/main/resources/META-INF/services/org/apache/camel/component/jira
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.component.jira.JIRAComponent
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/camel-jira/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/components/camel-jira/src/main/resources/log4j.properties b/components/camel-jira/src/main/resources/log4j.properties
new file mode 100644
index 0000000..4621723
--- /dev/null
+++ b/components/camel-jira/src/main/resources/log4j.properties
@@ -0,0 +1,16 @@
+
+#
+# The logging properties used
+#
+log4j.rootLogger=INFO, out
+
+# uncomment the following line to turn on Camel debugging
+#log4j.logger.org.apache.camel=DEBUG
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/f261f610/components/pom.xml
----------------------------------------------------------------------
diff --git a/components/pom.xml b/components/pom.xml
index e185ace..99c82eb 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -120,6 +120,7 @@
<!-- camel-jibx doesn't work under JDK8, but may be build without tests -->
<module>camel-jibx</module>
<module>camel-jing</module>
+ <module>camel-jira</module>
<module>camel-jmx</module>
<module>camel-josql</module>
<module>camel-jpa</module>