Added first version of the Camel Firebase component.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/3ad2f2b6 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/3ad2f2b6 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/3ad2f2b6 Branch: refs/heads/master Commit: 3ad2f2b6cb82fbf1052fc80a178b14d3ced9e073 Parents: 8cb830b Author: gilfernandes <[email protected]> Authored: Fri Nov 18 15:57:33 2016 +0000 Committer: Andrea Cosentino <[email protected]> Committed: Fri Nov 25 10:05:35 2016 +0100 ---------------------------------------------------------------------- components/camel-firebase/pom.xml | 65 ++++++ .../component/firebase/FirebaseComponent.java | 37 ++++ .../component/firebase/FirebaseConfig.java | 103 ++++++++++ .../component/firebase/FirebaseConsumer.java | 82 ++++++++ .../component/firebase/FirebaseEndpoint.java | 97 +++++++++ .../component/firebase/FirebaseProducer.java | 61 ++++++ .../firebase/data/FirebaseMessage.java | 88 ++++++++ .../component/firebase/data/Operation.java | 13 ++ .../exception/DatabaseErrorException.java | 16 ++ .../firebase/exception/FirebaseException.java | 57 ++++++ .../src/main/resources/META-INF/LICENSE.txt | 203 +++++++++++++++++++ .../org/apache/camel/component/firebase | 1 + .../firebase/FirebaseConsumerDeleteTest.java | 87 ++++++++ .../firebase/FirebaseConsumerTest.java | 77 +++++++ .../firebase/FirebaseProducerTest.java | 91 +++++++++ .../provider/ConfigurationProvider.java | 41 ++++ .../firebase/provider/SampleInputProvider.java | 44 ++++ ...-app-firebase-adminsdk-rcwg7-fea519a672.json | 12 ++ .../src/test/resources/log4j2.properties | 7 + .../src/test/resources/sample_message.txt | 1 + 20 files changed, 1183 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-firebase/pom.xml b/components/camel-firebase/pom.xml new file mode 100644 index 0000000..ad76990 --- /dev/null +++ b/components/camel-firebase/pom.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>components</artifactId> + <groupId>org.apache.camel</groupId> + <version>2.19.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <name>Camel :: Firebase</name> + + <artifactId>camel-firebase</artifactId> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <firebase.version>4.0.1</firebase.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-core</artifactId> + </dependency> + <!-- compile 'com.google.firebase:firebase-database:9.8.0' --> + <dependency> + <groupId>com.google.firebase</groupId> + <artifactId>firebase-admin</artifactId> + <version>${firebase.version}</version> + </dependency> + + <!-- testing --> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test</artifactId> + <scope>test</scope> + </dependency> + <!-- https://mvnrepository.com/artifact/org.assertj/assertj-core --> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <version>3.5.2</version> + <scope>test</scope> + </dependency> + </dependencies> + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseComponent.java b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseComponent.java new file mode 100644 index 0000000..18e6d64 --- /dev/null +++ b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseComponent.java @@ -0,0 +1,37 @@ +package org.apache.camel.component.firebase; + +import org.apache.camel.CamelContext; +import org.apache.camel.Endpoint; +import org.apache.camel.impl.UriEndpointComponent; + +import java.util.Map; + +/** + * Represents the component that manages {@link FirebaseEndpoint}. + */ +public class FirebaseComponent extends UriEndpointComponent { + + public FirebaseComponent() { + super(FirebaseEndpoint.class); + } + + public FirebaseComponent(CamelContext context) { + super(context, FirebaseEndpoint.class); + } + + protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { + + FirebaseConfig firebaseConfig = new FirebaseConfig.Builder( + String.format("https://%s", remaining), + (String) parameters.get("rootReference"), + (String) parameters.get("serviceAccountFile")) + .build(); + + firebaseConfig.init(); + + Endpoint endpoint = new FirebaseEndpoint(uri, this, firebaseConfig); + setProperties(endpoint, parameters); + return endpoint; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseConfig.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseConfig.java b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseConfig.java new file mode 100644 index 0000000..a46caf8 --- /dev/null +++ b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseConfig.java @@ -0,0 +1,103 @@ +package org.apache.camel.component.firebase; + +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.UUID; + +/** + * Contains the elements needed to connect to Firebase + */ +public class FirebaseConfig { + + private final String databaseUrl; + + private final String rootReference; + + private final String serviceAccountFile; + + private final String keyName; + + private final boolean async; + + private FirebaseApp firebaseApp; + + private FirebaseConfig(Builder builder) { + this.databaseUrl = builder.databaseUrl; + this.rootReference = builder.rootReference; + this.serviceAccountFile = builder.serviceAccountFile; + this.keyName = builder.keyName; + this.async = builder.async; + } + + public void init() throws IOException { + try(InputStream in = Files.newInputStream(Paths.get(serviceAccountFile))) { + FirebaseOptions options = new FirebaseOptions.Builder() + .setServiceAccount(in) + .setDatabaseUrl(this.databaseUrl) + .build(); + firebaseApp = FirebaseApp.initializeApp(options, UUID.randomUUID().toString()); + } + } + + public String getDatabaseUrl() { + return databaseUrl; + } + + public String getRootReference() { + return rootReference; + } + + public String getServiceAccountFile() { + return serviceAccountFile; + } + + public String getKeyName() { + return keyName; + } + + public FirebaseApp getFirebaseApp() { + return firebaseApp; + } + + public boolean isAsync() { + return async; + } + + public static class Builder { + + private final String databaseUrl; + + private final String rootReference; + + private final String serviceAccountFile; + + private String keyName; + + private boolean async; + + public Builder(String databaseUrl, String rootReference, String serviceAccountFile) { + this.databaseUrl = databaseUrl; + this.rootReference = rootReference; + this.serviceAccountFile = serviceAccountFile; + } + + public Builder setKeyName(String keyName) { + this.keyName = keyName; + return this; + } + + public Builder setAsync(boolean async) { + this.async = async; + return this; + } + + public FirebaseConfig build() { + return new FirebaseConfig(this); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseConsumer.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseConsumer.java b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseConsumer.java new file mode 100644 index 0000000..1dee1a4 --- /dev/null +++ b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseConsumer.java @@ -0,0 +1,82 @@ +package org.apache.camel.component.firebase; + +import com.google.firebase.database.ChildEventListener; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.FirebaseDatabase; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.firebase.data.FirebaseMessage; +import org.apache.camel.component.firebase.data.Operation; +import org.apache.camel.component.firebase.exception.FirebaseException; +import org.apache.camel.impl.DefaultConsumer; + +/** + * Listens to child events of the root reference and forwards the incoming message on the route. + */ +public class FirebaseConsumer extends DefaultConsumer { + + private final FirebaseConfig firebaseConfig; + + private final FirebaseEndpoint endpoint; + + public FirebaseConsumer(FirebaseEndpoint endpoint, Processor processor) { + super(endpoint, processor); + this.endpoint = endpoint; + firebaseConfig = endpoint.getFirebaseConfig(); + } + + @Override + protected void doStart() throws Exception { + FirebaseDatabase + .getInstance(endpoint.getFirebaseApp()) + .getReference(firebaseConfig.getRootReference()) + .addChildEventListener(new ChildEventListener() { + @Override + public void onChildAdded(DataSnapshot dataSnapshot, String s) { + forwardMessage(new FirebaseMessage.Builder(Operation.CHILD_ADD, dataSnapshot) + .setPreviousChildName(s).build()); + } + + @Override + public void onChildChanged(DataSnapshot dataSnapshot, String s) { + forwardMessage(new FirebaseMessage.Builder(Operation.CHILD_CHANGED, dataSnapshot) + .setPreviousChildName(s).build()); + } + + @Override + public void onChildRemoved(DataSnapshot dataSnapshot) { + forwardMessage(new FirebaseMessage.Builder(Operation.CHILD_REMOVED, dataSnapshot).build()); + } + + @Override + public void onChildMoved(DataSnapshot dataSnapshot, String s) { + forwardMessage(new FirebaseMessage.Builder(Operation.CHILD_MOVED, dataSnapshot) + .setPreviousChildName(s).build()); + } + + @Override + public void onCancelled(DatabaseError databaseError) { + forwardMessage(new FirebaseMessage.Builder(Operation.CANCELLED).setDatabaseError(databaseError) + .build()); + } + }); + } + + private void forwardMessage(FirebaseMessage o) { + Exchange exchange = endpoint.createExchange(); + exchange.getIn().setBody(o); + + try { + // send message to next processor in the route + getProcessor().process(exchange); + } catch (Exception e) { + throw new FirebaseException("Message forwarding failed", e); + } finally { + // log exception if an exception occurred and was not handled + if (exchange.getException() != null) { + getExceptionHandler().handleException("Error processing exchange", exchange, exchange.getException()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseEndpoint.java b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseEndpoint.java new file mode 100644 index 0000000..0be796a --- /dev/null +++ b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseEndpoint.java @@ -0,0 +1,97 @@ +package org.apache.camel.component.firebase; + +import com.google.firebase.FirebaseApp; +import org.apache.camel.Consumer; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.impl.DefaultEndpoint; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.UriEndpoint; +import org.apache.camel.spi.UriParam; + +/** + * Represents a Firebase endpoint. + */ +@UriEndpoint(scheme = "firebase", title = "Firebase", syntax="firebase:name", consumerClass = FirebaseConsumer.class, label = "Firebase") +public class FirebaseEndpoint extends DefaultEndpoint { + + private final FirebaseConfig firebaseConfig; + + @UriParam + @Metadata(required = "true") + private String rootReference; + + @UriParam + @Metadata(required = "true") + private String serviceAccountFile; + + @UriParam(defaultValue = "firebaseKey") @Metadata(required = "false") + private String keyName = "firebaseKey"; + + @UriParam(defaultValue = "async") @Metadata(required = "false") + private boolean async; + + public FirebaseEndpoint(String uri, FirebaseComponent firebaseComponent, FirebaseConfig firebaseConfig) { + super(uri, firebaseComponent); + this.firebaseConfig = firebaseConfig; + this.setRootReference(firebaseConfig.getRootReference()); + this.setServiceAccountFile(firebaseConfig.getServiceAccountFile()); + final String keyName = firebaseConfig.getKeyName(); + this.setAsync(firebaseConfig.isAsync()); + if(keyName != null) { + this.setKeyName(keyName); + } + } + + public Producer createProducer() throws Exception { + return new FirebaseProducer(this); + } + + public Consumer createConsumer(Processor processor) throws Exception { + return new FirebaseConsumer(this, processor); + } + + public boolean isSingleton() { + return true; + } + + public String getRootReference() { + return rootReference; + } + + public void setRootReference(String rootReference) { + this.rootReference = rootReference; + } + + public String getServiceAccountFile() { + return serviceAccountFile; + } + + public void setServiceAccountFile(String serviceAccountFile) { + this.serviceAccountFile = serviceAccountFile; + } + + public FirebaseConfig getFirebaseConfig() { + return firebaseConfig; + } + + public String getKeyName() { + return keyName; + } + + public void setKeyName(String keyName) { + this.keyName = keyName; + } + + public boolean isAsync() { + return async; + } + + public void setAsync(boolean async) { + this.async = async; + } + + public FirebaseApp getFirebaseApp() { + return firebaseConfig.getFirebaseApp(); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseProducer.java b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseProducer.java new file mode 100644 index 0000000..bc09550 --- /dev/null +++ b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/FirebaseProducer.java @@ -0,0 +1,61 @@ +package org.apache.camel.component.firebase; + +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import org.apache.camel.AsyncCallback; +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.Processor; +import org.apache.camel.component.firebase.exception.DatabaseErrorException; +import org.apache.camel.impl.DefaultAsyncProducer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The producer, which can be used to set a value for a specific key in Firebase. + */ +public class FirebaseProducer extends DefaultAsyncProducer { + + private static final Logger LOG = LoggerFactory.getLogger(FirebaseProducer.class); + private final String rootReference; + private final FirebaseEndpoint endpoint; + + public FirebaseProducer(FirebaseEndpoint endpoint) { + super(endpoint); + this.endpoint = endpoint; + rootReference = endpoint.getRootReference(); + } + + /** + * Processes the message exchange. + * Similar to {@link Processor#process}, but the caller supports having the exchange asynchronously processed. + * <p/> + * If there was a failure processing then the caused {@link Exception} would be set on the {@link Exchange}. + * + * @param exchange the message exchange + * @param callback the {@link AsyncCallback} will be invoked when the processing of the exchange is completed. + * If the exchange is completed synchronously, then the callback is also invoked synchronously. + * The callback should therefore be careful of starting recursive loop. + * @return (doneSync) <tt>true</tt> to continue execute synchronously, <tt>false</tt> to continue being executed asynchronously + */ + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + final Message in = exchange.getIn(); + String firebaseKey = (String) in.getHeader(endpoint.getKeyName()); + Object value = in.getBody(); + DatabaseReference ref = FirebaseDatabase + .getInstance(endpoint.getFirebaseApp()) + .getReference(rootReference).child(firebaseKey); + ref.setValue(value, (DatabaseError databaseError, DatabaseReference databaseReference) -> { + if (databaseError != null) { + exchange.setException(new DatabaseErrorException(databaseError)); + exchange.getOut().setFault(true); + } else { + exchange.getOut().setBody(databaseReference); + } + callback.done(endpoint.isAsync()); + }); + return endpoint.isAsync(); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/data/FirebaseMessage.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/data/FirebaseMessage.java b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/data/FirebaseMessage.java new file mode 100644 index 0000000..afd02ae --- /dev/null +++ b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/data/FirebaseMessage.java @@ -0,0 +1,88 @@ +package org.apache.camel.component.firebase.data; + +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; + +/** + * Contains a message sent by Firebase. + */ +public class FirebaseMessage { + + private final Operation operation; + + private final DataSnapshot dataSnapshot; + + private final String previousChildName; + + private final DatabaseError databaseError; + + private FirebaseMessage(Builder builder) { + this.operation = builder.operation; + this.dataSnapshot = builder.dataSnapshot; + this.previousChildName = builder.previousChildName; + this.databaseError = builder.databaseError; + } + + public Operation getOperation() { + return operation; + } + + public DataSnapshot getDataSnapshot() { + return dataSnapshot; + } + + public String getPreviousChildName() { + return previousChildName; + } + + public DatabaseError getDatabaseError() { + return databaseError; + } + + @Override + public String toString() { + return "FirebaseMessage{" + "operation=" + operation + + ", dataSnapshot=" + dataSnapshot + + ", previousChildName='" + previousChildName + '\'' + + ", databaseError=" + databaseError + + '}'; + } + + public static class Builder { + private final Operation operation; + + private DataSnapshot dataSnapshot; + + private String previousChildName; + + private DatabaseError databaseError; + + public Builder(Operation operation) { + this.operation = operation; + } + + public Builder(Operation operation, DataSnapshot dataSnapshot) { + this.operation = operation; + this.dataSnapshot = dataSnapshot; + } + + public Builder setPreviousChildName(String previousChildName) { + this.previousChildName = previousChildName; + return this; + } + + public Builder setDataSnapshot(DataSnapshot dataSnapshot) { + this.dataSnapshot = dataSnapshot; + return this; + } + + public Builder setDatabaseError(DatabaseError databaseError) { + this.databaseError = databaseError; + return this; + } + + public FirebaseMessage build() { + return new FirebaseMessage(this); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/data/Operation.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/data/Operation.java b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/data/Operation.java new file mode 100644 index 0000000..5410c61 --- /dev/null +++ b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/data/Operation.java @@ -0,0 +1,13 @@ +package org.apache.camel.component.firebase.data; + +/** + * Operations associated with the messages. + */ +public enum Operation { + + CHILD_ADD, + CHILD_CHANGED, + CHILD_REMOVED, + CHILD_MOVED, + CANCELLED +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/exception/DatabaseErrorException.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/exception/DatabaseErrorException.java b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/exception/DatabaseErrorException.java new file mode 100644 index 0000000..4c2d23e --- /dev/null +++ b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/exception/DatabaseErrorException.java @@ -0,0 +1,16 @@ +package org.apache.camel.component.firebase.exception; + +import com.google.firebase.database.DatabaseError; + +/** + * In case Firebase throws a database error, this object wraps a Throwable around the original object. + */ +public class DatabaseErrorException extends RuntimeException { + + private final DatabaseError databaseError; + + public DatabaseErrorException(DatabaseError databaseError) { + super(); + this.databaseError = databaseError; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/exception/FirebaseException.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/exception/FirebaseException.java b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/exception/FirebaseException.java new file mode 100644 index 0000000..190f386 --- /dev/null +++ b/components/camel-firebase/src/main/java/org/apache/camel/component/firebase/exception/FirebaseException.java @@ -0,0 +1,57 @@ +package org.apache.camel.component.firebase.exception; + +import com.google.firebase.database.DatabaseError; + +/** + * Used to mark an exception occurred in the Firebase Camel processor. + */ +public class FirebaseException extends RuntimeException { + + private DatabaseError databaseError; + + /** + * Constructs a new runtime exception with {@code null} as its + * detail message. The cause is not initialized, and may subsequently be + * initialized by a call to {@link #initCause}. + */ + public FirebaseException() { + } + + /** + * Constructs a new runtime exception with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public FirebaseException(String message) { + super(message); + } + + /** + * Constructs a new runtime exception with the specified detail message and + * cause. <p>Note that the detail message associated with + * {@code cause} is <i>not</i> automatically incorporated in + * this runtime exception's detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A <tt>null</tt> value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public FirebaseException(String message, Throwable cause) { + super(message, cause); + } + + public void setDatabaseError(DatabaseError databaseError) { + this.databaseError = databaseError; + } + + public DatabaseError getDatabaseError() { + return databaseError; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/resources/META-INF/LICENSE.txt ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/resources/META-INF/LICENSE.txt b/components/camel-firebase/src/main/resources/META-INF/LICENSE.txt new file mode 100644 index 0000000..5861116 --- /dev/null +++ b/components/camel-firebase/src/main/resources/META-INF/LICENSE.txt @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 Onepoint Ltd + + Licensed 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. + http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/main/resources/META-INF/services/org/apache/camel/component/firebase ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/main/resources/META-INF/services/org/apache/camel/component/firebase b/components/camel-firebase/src/main/resources/META-INF/services/org/apache/camel/component/firebase new file mode 100644 index 0000000..24a2a7b7 --- /dev/null +++ b/components/camel-firebase/src/main/resources/META-INF/services/org/apache/camel/component/firebase @@ -0,0 +1 @@ +class=org.apache.camel.component.firebase.FirebaseComponent http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseConsumerDeleteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseConsumerDeleteTest.java b/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseConsumerDeleteTest.java new file mode 100644 index 0000000..460a7e7 --- /dev/null +++ b/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseConsumerDeleteTest.java @@ -0,0 +1,87 @@ +package org.apache.camel.component.firebase; + +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.firebase.data.FirebaseMessage; +import org.apache.camel.component.firebase.data.Operation; +import org.apache.camel.component.firebase.provider.ConfigurationProvider; +import org.apache.camel.component.firebase.provider.SampleInputProvider; +import org.apache.camel.impl.DefaultCamelContext; +import org.junit.Test; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import static junit.framework.TestCase.fail; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Starts a route which listens to the remove event in Firebase. It then writes and deletes an entry in Firebase and + * asserts, if the entry was deleted or not. + */ +public class FirebaseConsumerDeleteTest { + + private final ReentrantLock reentrantLock = new ReentrantLock(); + + private final Condition wake = reentrantLock.newCondition(); + + @Test + public void whenDelete_DeleteMessageShouldBeIntercepted() throws Exception { + CamelContext context = new DefaultCamelContext(); + boolean[] deleteMessageReceived = { false }; + FirebaseConfig firebaseConfig = ConfigurationProvider.createDemoConfig(); + setupRoute(context, deleteMessageReceived); + context.addStartupListener((context1, alreadyStarted) -> { + TimeUnit.SECONDS.sleep(5); + createAndDeleteContent(firebaseConfig); + }); + context.start(); + try { + reentrantLock.lock(); + wake.await(30, TimeUnit.SECONDS); + } finally { + reentrantLock.unlock(); + } + assertThat(deleteMessageReceived[0]).isTrue(); + context.stop(); + } + + private void createAndDeleteContent(FirebaseConfig firebaseConfig) { + final DatabaseReference rootReference = FirebaseDatabase.getInstance(firebaseConfig.getFirebaseApp()) + .getReference(ConfigurationProvider.createRootReference()).child(SampleInputProvider.createDeleteKey()); + rootReference + .setValue("AETHELWULF 839-856", (databaseError, databaseReference) -> { + databaseReference.removeValue(); + }); + } + + private void setupRoute(CamelContext context, final boolean[] deleteMessageReceived) throws Exception { + context.addRoutes(new RouteBuilder() { + public void configure() { + try { + from(String.format("firebase://%s?rootReference=%s&serviceAccountFile=%s", + ConfigurationProvider.createDatabaseUrl(), ConfigurationProvider.createRootReference(), ConfigurationProvider.createFirebaseConfigLink())) + .to("log:firebasetest?level=WARN") + .process(exchange -> { + FirebaseMessage firebaseMessage = (FirebaseMessage) exchange.getIn().getBody(); + if (firebaseMessage.getOperation() == Operation.CHILD_REMOVED) { + deleteMessageReceived[0] = true; + try { + reentrantLock.lock(); + wake.signal(); + } finally { + reentrantLock.unlock(); + } + } + }); + + } catch (Exception e) { + fail(e.toString()); + } + } + }); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseConsumerTest.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseConsumerTest.java b/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseConsumerTest.java new file mode 100644 index 0000000..2c6cbc4 --- /dev/null +++ b/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseConsumerTest.java @@ -0,0 +1,77 @@ +package org.apache.camel.component.firebase; + +import com.google.firebase.database.FirebaseDatabase; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.firebase.provider.ConfigurationProvider; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +import java.io.IOException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Writes a dummy message and then checks, if the consumer receives at least one message. + */ +public class FirebaseConsumerTest extends CamelTestSupport { + + @Test + public void whenFirebaseListener_ShouldReceiveMessages() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedMinimumMessageCount(1); + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + final String databaseUrl = "gil-sample-app.firebaseio.com"; + final String originalRootReference = "server/saving-data"; + String serviceAccountFile = ConfigurationProvider.createFirebaseConfigLink(); + String rootReference = URLEncoder.encode(originalRootReference, "UTF-8"); + insertDummyData(String.format("https://%s", databaseUrl), originalRootReference, serviceAccountFile); + + return new RouteBuilder() { + public void configure() { + try { + from(String.format("firebase://" + databaseUrl + "?rootReference=%s&serviceAccountFile=%s", + rootReference, serviceAccountFile)) + .to("log:firebasetest?level=WARN") + .to("mock:result"); + } catch (Exception e) { + fail(e.toString()); + } + } + }; + } + + private final ReentrantLock lock = new ReentrantLock(); + + private final Condition wake = lock.newCondition(); + + private void insertDummyData(String databaseUrl, String originalRootReference, String serviceAccountFile) throws IOException, InterruptedException { + FirebaseConfig config = new FirebaseConfig.Builder(databaseUrl, originalRootReference, URLDecoder.decode(serviceAccountFile, "UTF-8")) + .build(); + config.init(); + FirebaseDatabase + .getInstance(config.getFirebaseApp()) + .getReference(config.getRootReference()).child("dummy").setValue("test", (databaseError, databaseReference) -> { + try { + lock.lock(); + wake.signal(); + } + finally { + lock.unlock(); + } + }); + try { + lock.lock(); + wake.await(); + } + finally { + lock.unlock(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseProducerTest.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseProducerTest.java b/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseProducerTest.java new file mode 100644 index 0000000..75dd869 --- /dev/null +++ b/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/FirebaseProducerTest.java @@ -0,0 +1,91 @@ +package org.apache.camel.component.firebase; + +import com.google.firebase.database.DatabaseReference; +import org.apache.camel.CamelContext; +import org.apache.camel.Message; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.GenericFile; +import org.apache.camel.component.firebase.provider.ConfigurationProvider; +import org.apache.camel.component.firebase.provider.SampleInputProvider; +import org.apache.camel.impl.DefaultCamelContext; +import org.junit.Before; +import org.junit.Test; + +import java.net.URLEncoder; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +/** + * Tests two scenarios: a synchronous and one asynchronous request. + */ +public class FirebaseProducerTest { + + private final ReentrantLock reentrantLock = new ReentrantLock(); + + private final Condition wake = reentrantLock.newCondition(); + + private SampleInputProvider sampleInputProvider; + + @Before + public void setUp() throws Exception { + sampleInputProvider = new SampleInputProvider(); + } + + @Test + public void whenFirebaseSet_ShouldReceiveMessagesSync() throws Exception { + startRoute(false, DatabaseReference.class); + } + + @Test + public void whenFirebaseSet_ShouldReceiveMessagesAsync() throws Exception { + startRoute(true, String.class); + } + + + private void startRoute(final boolean async, final Class<?> expectedBodyClass) throws Exception { + sampleInputProvider.copySampleFile(); + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + String rootReference = URLEncoder.encode(ConfigurationProvider.createRootReference(), "UTF-8"); + String serviceAccountFile = ConfigurationProvider.createFirebaseConfigLink(); + from(sampleInputProvider.getTargetFolder().toUri().toString()) + .process(exchange -> { + GenericFile file = (GenericFile) exchange.getIn().getBody(); + String content = new String(Files.readAllBytes(Paths.get(file.getAbsoluteFilePath())), "UTF-8"); + String[] keyValue = content.split("="); + final Message out = exchange.getOut(); + out.setHeader("firebaseKey", keyValue[0]); + out.setBody(keyValue[1].trim()); + }) + .to(String.format("firebase://%s?rootReference=%s&serviceAccountFile=%s&async=%b", + ConfigurationProvider.createDatabaseUrl(), rootReference, serviceAccountFile, async)) + .to("log:whenFirebaseSet?level=WARN") + .process(exchange1 -> { + assertThat(exchange1.getIn().getBody().getClass()).isEqualTo(expectedBodyClass); + try{ + reentrantLock.lock(); + wake.signal(); + } + finally { + reentrantLock.unlock(); + } + }); + } + }); + context.start(); + try{ + reentrantLock.lock(); + wake.await(); + } + finally { + reentrantLock.unlock(); + } + context.stop(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/provider/ConfigurationProvider.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/provider/ConfigurationProvider.java b/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/provider/ConfigurationProvider.java new file mode 100644 index 0000000..666abf7 --- /dev/null +++ b/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/provider/ConfigurationProvider.java @@ -0,0 +1,41 @@ +package org.apache.camel.component.firebase.provider; + +import org.apache.camel.component.firebase.FirebaseConfig; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLDecoder; +import java.net.URLEncoder; + +import static org.junit.Assert.assertNotNull; + +/** + * Provides the path of the configuration used to access Firebase. + */ +public class ConfigurationProvider { + + public static String createFirebaseConfigLink() throws URISyntaxException, UnsupportedEncodingException { + URL url = Thread.currentThread().getContextClassLoader().getResource("gil-sample-app-firebase-adminsdk-rcwg7-fea519a672.json"); + assertNotNull(url); + File f = new File(url.toURI()); + return URLEncoder.encode(f.getAbsolutePath(), "UTF-8"); + } + + public static FirebaseConfig createDemoConfig() throws IOException, URISyntaxException { + FirebaseConfig firebaseConfig = new FirebaseConfig.Builder(String.format("https://%s", createDatabaseUrl()), createRootReference(), + URLDecoder.decode(createFirebaseConfigLink(), "UTF-8")).build(); + firebaseConfig.init(); + return firebaseConfig; + } + + public static String createRootReference() { + return "server/saving-data"; + } + + public static String createDatabaseUrl() { + return "gil-sample-app.firebaseio.com"; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/provider/SampleInputProvider.java ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/provider/SampleInputProvider.java b/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/provider/SampleInputProvider.java new file mode 100644 index 0000000..4b0d4f7 --- /dev/null +++ b/components/camel-firebase/src/test/java/org/apache/camel/component/firebase/provider/SampleInputProvider.java @@ -0,0 +1,44 @@ +package org.apache.camel.component.firebase.provider; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Copies a test file to a folder to test routes. + */ +public class SampleInputProvider { + + private final Path targetFolder; + + public SampleInputProvider() throws IOException { + targetFolder = Paths.get("src/data"); + if(!Files.exists(targetFolder)) { + Files.createDirectories(targetFolder); + } + } + + public void copySampleFile() throws URISyntaxException, IOException { + final String name = "sample_message.txt"; + URL url = Thread.currentThread().getContextClassLoader().getResource(name); + assertThat(url).isNotNull(); + final URI uri = url.toURI(); + Path sourceFile = Paths.get(uri); + Files.copy(sourceFile, targetFolder.resolve(name), StandardCopyOption.REPLACE_EXISTING); + } + + public Path getTargetFolder() { + return targetFolder; + } + + public static String createDeleteKey() { + return "second king of Saxony"; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/test/resources/gil-sample-app-firebase-adminsdk-rcwg7-fea519a672.json ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/test/resources/gil-sample-app-firebase-adminsdk-rcwg7-fea519a672.json b/components/camel-firebase/src/test/resources/gil-sample-app-firebase-adminsdk-rcwg7-fea519a672.json new file mode 100644 index 0000000..7a9f352 --- /dev/null +++ b/components/camel-firebase/src/test/resources/gil-sample-app-firebase-adminsdk-rcwg7-fea519a672.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "gil-sample-app", + "private_key_id": "fea519a672d21f7667afb1badbeb858342ae32ac", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDX88p2HcAn2z0t\n7uAk0jB0RUyi4f+SWd3ofM6Ju59XLyttnbXKEYNBnjIE3YOJ49Xd92vFXGsYU+DU\nb7vFf/rXtfiZglE6zHF8p+53Jy/AJKWHLWKa+nZa4vUQASmBGJy5SF37YJhaE/Mu\nUqNESdZowdjro4bE3D/VYZsK/9UmHEO8PmlKL9Igl4WVq5I1toJk1eae/2nBmE3+\n3/uGrTf6ydJ8xx/tPMwWGLRNYxb4PQliTTCaLc5dR/p9B8YMwMtuxWU9IereIKp8\n51ZgYW6e/6IHbfb22cp2NwKHxwvnZu5HZ1+IIZ+3n9S2OJYZGPBIB7xJzSd6xXAf\nXAQqYzMDAgMBAAECggEAYfbEJ6UDYJFCRa4RnGKFfJlbVKC1MYz279p+T1j/xasu\nRkG/D/W113SOOErMuybSBCmTiCqOorCaU4SEZ+nQvz5bkjfd5ZCNAwGjWgY60S1O\nse3Sx39LZZuDlEkSrO+fWSYNDFYbhvF55c+zJO1iCI+3ed3q6y8G/iOTFABOj0R5\nZ7pPJqzXIg3sKRaMOJ+l2F8/nIZ8AUyesByJgP4UuyYTb9LaqRqIz/URYh2xVohW\n3MkXmCDkY5tyzJ7rwJloHoOo4Hsvefzgv3dDJYu4FJ7BUHFyNa6yZDGdte49WQsS\nDNEwEDvBPsE00olbsjAkSpdC0u57836Vn81Xz84y4QKBgQD63EWzFrVx0w+8PSy8\nPqZgQWEwHb09r2c9TjaxqohtapqFZZ5szEiOOad8r369RQ6bVIMzYzYRBUGDkZj7\nmDBB1lglgYC+NEHZAaObXPzVngAN3fRW7a+IRQLOlYqd8Er0v0jw37R6PjAXFz/5\nFtnX0eMnA0MfNqN9mhKyvgX7mQ KBgQDcYG4sUOSIO3BG7z9ufL0aiyfERFg6gTJ1\n05xXVNHJBRh+nu6bXPp+a76myiR0QPhXhKuok7PC4opcmreeN4401MGSStgp4Xng\nM/vpMd3knw0zn9DY5FrFdxtIs8YFBcu2XkJzz+rM1IAw563wLRQAuUbb+AOtspZ1\noDZ2ssQk+wKBgE+Oa8xP91sRxHu+KuHIPJtqIJhR1iIp7mPS2iWeH4YTuM11XLjE\nUH5KaoNwZJFBxVAdjT5OyGa9c/l1wz6HFUbL40iBuYKYsAlSK8CpzMUyRnIfYc3v\nsytUN3+sjTlpa1wTDd7WEzZxYm7wQKmORafcOF22+yJ7AX5jzmpBOUSBAoGBAIkY\nLDHBeQoPAAAA4hMX4oRawThl1AVBTmTiacYibAeD9gL/WCyqoOJ4oLgd1KPFrziy\nvh83E4NPbwfA8C2rHfpbyLf7e5JCRJFnhXVCommRUKMm7sOe+6EQQZbuz2dcfahL\n50cot0cJg13pItnhESqKGDzLg25RRSyTqI4bE851AoGAHAixBamIjbFDuSxx9wQ6\n8qy1eB0h66BvZ+YWrXaI6v9zBBSRrdnda35oFVAOFV4LZ6NNsg88ODX/kt9vU5CB\nEmQYAwLLh6vrmw59JifoNIv47GnxGbpCkp9SFhmkiJbyAJiEjAjAtz8HulY1Biqs\nGHkPENC3ZATt4yXI76C5ktU=\n-----END PRIVATE KEY-----\n", + "client_email": "[email protected]", + "client_id": "107121076566697579073", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://accounts.google.com/o/oauth2/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-rcwg7%40gil-sample-app.iam.gserviceaccount.com" +} http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/test/resources/log4j2.properties ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/test/resources/log4j2.properties b/components/camel-firebase/src/test/resources/log4j2.properties new file mode 100644 index 0000000..328db35 --- /dev/null +++ b/components/camel-firebase/src/test/resources/log4j2.properties @@ -0,0 +1,7 @@ + +appender.out.type = Console +appender.out.name = out +appender.out.layout.type = PatternLayout +appender.out.layout.pattern = [%30.30t] %-30.30c{1} %-5p %m%n +rootLogger.level = INFO +rootLogger.appenderRef.out.ref = out http://git-wip-us.apache.org/repos/asf/camel/blob/3ad2f2b6/components/camel-firebase/src/test/resources/sample_message.txt ---------------------------------------------------------------------- diff --git a/components/camel-firebase/src/test/resources/sample_message.txt b/components/camel-firebase/src/test/resources/sample_message.txt new file mode 100644 index 0000000..852f717 --- /dev/null +++ b/components/camel-firebase/src/test/resources/sample_message.txt @@ -0,0 +1 @@ +FIRST KIND OF ENGLAND=Egbert \ No newline at end of file
