--- /dev/null
+<?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">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>de.rxjava.tests</groupId>
+ <artifactId>rxjava-tests</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <name>rxjava-tests</name>
+ <url>http://gumartinm.name</url>
+ <description>SQL Tests</description>
+ <organization>
+ <name>Gustavo Martin Morcuende</name>
+ <url>http://www.gumartinm.name</url>
+ </organization>
+ <scm>
+ <developerConnection>scm:git:http://git.gumartinm.name/JavaForFun</developerConnection>
+ <url>http://git.gumartinm.name/JavaForFun</url>
+ </scm>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <dependencies>
+ <!-- 1/3 Required dependency for log4j 2 with slf4j: binding between log4j
+ 2 and slf4j -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <version>2.3</version>
+ </dependency>
+
+ <!-- 2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin
+ (it is the log4j 2 implementation) -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.3</version>
+ </dependency>
+
+ <!-- 3/3 Required dependency for getting rid of commons logging. This is
+ the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring)
+ and whatever I am using for logging (in this case I am using log4j 2) See:
+ http://www.slf4j.org/legacy.html We need exclusions in every dependency using
+ Jakarta Commons Logging (see Spring dependencies below) -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>1.7.12</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.reactivex</groupId>
+ <artifactId>rxjava</artifactId>
+ <version>1.2.3</version>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ <compilerArgument>-Xlint:deprecation</compilerArgument>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.7</version>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Specification-Title>${project.description}</Specification-Title>
+ <Specification-Version>${project.version}</Specification-Version>
+ <Specification-Vendor>${project.organization.name}</Specification-Vendor>
+ <Implementation-Title>${project.description}</Implementation-Title>
+ <Implementation-Version>${project.version}</Implementation-Version>
+ <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package de.rxjava.tests;
+
+import de.rxjava.tests.service.impl.AsyncHTTPClient;
+
+public class MainRxJava {
+
+ public static void main(String[] args) {
+ AsyncHTTPClient asyncHTTPClient = new AsyncHTTPClient();
+
+ asyncHTTPClient.getPages();
+ }
+}
--- /dev/null
+/**
+ * Copyright 2014 Gustavo Martin Morcuende
+ *
+ * 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.
+ */
+package de.rxjava.tests.httpclient;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.Charset;
+
+public class CustomHTTPClient {
+ private final String userAgent;
+
+ private CustomHTTPClient(String userAgent) {
+ this.userAgent = userAgent;
+ }
+
+ public String retrieveDataAsString(final URL url) throws IOException {
+ final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ try {
+ connection.setRequestProperty("User-Agent", userAgent);
+ connection.setRequestProperty("Cache-Control", "no-cache");
+ final InputStream in = new BufferedInputStream(connection.getInputStream());
+ final ByteArrayOutputStream buffer = readInputStream(in);
+ // No easy way of retrieving the charset from urlConnection.getContentType()
+ // Currently OpenWeatherMap returns: application/json; charset=utf-8
+ // Let's hope they will not change the content-type :/
+ return new String(buffer.toByteArray(), Charset.forName("UTF-8"));
+ } finally {
+ connection.disconnect();
+ }
+ }
+
+ private ByteArrayOutputStream readInputStream (final InputStream inputStream) throws IOException {
+ final ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
+ final int bufferSize = 1024;
+ final byte[] buffer = new byte[bufferSize];
+
+ int len = 0;
+ while ((len = inputStream.read(buffer)) != -1) {
+ byteBuffer.write(buffer, 0, len);
+ }
+
+ return byteBuffer;
+ }
+
+ public static final CustomHTTPClient newInstance(final String userAgent) {
+ return new CustomHTTPClient(userAgent);
+ }
+}
--- /dev/null
+package de.rxjava.tests.service.impl;
+
+import java.io.IOException;
+import java.net.URL;
+
+import de.rxjava.tests.httpclient.CustomHTTPClient;
+import rx.Observable;
+import rx.schedulers.Schedulers;
+
+public class AsyncHTTPClient {
+
+ public void getPages() {
+
+ getDataAsync("https://github.com/gumartinm")
+ // fancy Java way of using lambdas.
+ .subscribe(System.out::println); //The subscribe method starts to run the code implemented in getDataSync
+ //subscribeOn just declares who is going to run my code (a pool of threads)
+ //subscribe is the guy who starts to run my code!!!
+ //JavaScript does the same with Promises but in a cleaner way (IMHO), it does not
+ //need a subscribe method for starting the machinery (the machinery is underneath
+ //implemented by the Web Browser with its asynchronous callbacks)
+ getDataAsync("http://www.google.de").subscribe(page -> {
+ System.out.println("Another way, no so cool (with lambdas)");
+ System.out.println(Thread.currentThread().getName());
+ System.out.println(page);
+ });
+
+
+ System.out.println("YOU SEE ME FIRST!!!!");
+
+
+ try {
+ Thread.sleep(30000);
+ } catch (InterruptedException exception) {
+ }
+
+ }
+
+ private Observable<String> getDataAsync(String uri) {
+ return getDataSync(uri)
+ .subscribeOn(Schedulers.io()); // Creates a pool of threads for us which will run the code implemented below :)
+ // THIE METHOD DOES NOT START TO RUN MY CODE!!! IT IS DONE BY subscribe METHOD!!!
+ }
+
+ private Observable<String> getDataSync(String uri) {
+ return Observable.create(observer -> {
+ System.out.println(Thread.currentThread().getName());
+ String data = "";
+ try {
+ data = CustomHTTPClient.newInstance("RxJavaTest").retrieveDataAsString(new URL(uri));
+
+ // Making it slower as if having a bad connection :)
+ Thread.sleep(2000);
+ } catch (IOException | InterruptedException exception) {
+ observer.onError(exception);
+ }
+
+ // When do you use this stuff?
+ // observer.onCompleted();
+ observer.onNext(data);
+ });
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ status: The level of internal Log4j events that should be logged to the console.
+ Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
+
+ monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
+
+
+ see https://logging.apache.org/log4j/2.x/manual/configuration.html
+ -->
+<Configuration status="error" strict="true" monitorInterval="30"
+ name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+
+ <!--
+ ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
+
+ ERROR by default.
+ -->
+
+ <Appenders>
+ <Appender type="Console" name="STDOUT">
+ <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+ </Appender>
+ </Appenders>
+ <Loggers>
+
+
+ <!--
+ Anything else will be using INFO logging level.
+ -->
+ <Root level="INFO">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+
+ </Loggers>
+</Configuration>