Twitter functional apps
* Streaming source * Add twitter search and messasge sources * Add more twitter source, sink and processors * Add IT tests for twitter update sink * Add IT tests for twitter message sink * Add IT tests for twitter trend processor * twitter suppliers readme * twitter consumers readme * twitter functions readme * Disable TwitterStreamSourceTests
This commit is contained in:
committed by
Soby Chacko
parent
9bf8dcc4e7
commit
873f17414e
30
functions/function/twitter-function/README.adoc
Normal file
30
functions/function/twitter-function/README.adoc
Normal file
@@ -0,0 +1,30 @@
|
||||
# Twitter Functions
|
||||
|
||||
This module provides couple of twitter functions that can be reused and composed in other applications.
|
||||
|
||||
## Twitter Trend Function
|
||||
|
||||
Functions can return either Trends topics or the Locations of the trending topics. The `twitter.trend.trend-query-type` property allows choosing between both types.
|
||||
|
||||
* Trends - `twitter.trend.trend-query-type` is set to `trend`. Leverages the https://developer.twitter.com/en/docs/trends/trends-for-location/api-reference/get-trends-place[Trends API] to return the https://help.twitter.com/en/using-twitter/twitter-trending-faqs[trending topics] near a specific latitude, longitude location.
|
||||
|
||||
* Trend Locations - the `twitter.trend.trend-query-type` is set `trendLocation`. Retrieve a full or nearby locations list of trending topics by location. If the `latitude`, `longitude` parameters are NOT provided the processor performs the https://developer.twitter.com/en/docs/trends/locations-with-trending-topics/api-reference/get-trends-available[Trends Available API] and returns the locations that Twitter has trending topic information for.
|
||||
If the `latitude`, `longitude` parameters are provided the processor performs the https://developer.twitter.com/en/docs/trends/locations-with-trending-topics/api-reference/get-trends-closest[Trends Closest API] and returns the locations that Twitter has trending topic information for, closest to a specified location.
|
||||
|
||||
Response is an array of `locations` that encode the location's WOEID and some other human-readable information such as a canonical name and country the location belongs in.
|
||||
|
||||
### Beans for injection
|
||||
|
||||
You can import the `TwitterTrendFunctionConfiguration` in a Spring Boot application and then inject the following bean.
|
||||
|
||||
`filterFunction`
|
||||
|
||||
You can use `Function<Message<?>, Message<byte[]>> trendOrTrendLocationsFunction` as a qualifier when injecting.
|
||||
|
||||
Once injected, you can use the `apply` method of the `Function` to invoke it and get the result.
|
||||
|
||||
### Configuration Options
|
||||
|
||||
|
||||
### Other usage
|
||||
|
||||
46
functions/function/twitter-function/pom.xml
Normal file
46
functions/function/twitter-function/pom.xml
Normal file
@@ -0,0 +1,46 @@
|
||||
<?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>
|
||||
<artifactId>twitter-function</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>twitter-function</name>
|
||||
<description>twitter functions</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud.fn</groupId>
|
||||
<artifactId>spring-functions-parent</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../spring-functions-parent</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.fn</groupId>
|
||||
<artifactId>twitter-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-integration</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.cloud.fn.twitter.trend;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import twitter4j.GeoLocation;
|
||||
import twitter4j.Location;
|
||||
import twitter4j.Trends;
|
||||
import twitter4j.Twitter;
|
||||
import twitter4j.TwitterException;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.fn.common.twitter.TwitterConnectionConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(TwitterTrendFunctionProperties.class)
|
||||
@Import(TwitterConnectionConfiguration.class)
|
||||
public class TwitterTrendFunctionConfiguration {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(TwitterTrendFunctionConfiguration.class);
|
||||
|
||||
@Bean
|
||||
public Function<Message<?>, Trends> trend(TwitterTrendFunctionProperties properties, Twitter twitter) {
|
||||
return message -> {
|
||||
try {
|
||||
int woeid = properties.getLocationId().getValue(message, int.class);
|
||||
return twitter.getPlaceTrends(woeid);
|
||||
}
|
||||
catch (TwitterException e) {
|
||||
logger.error("Twitter API error!", e);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Function<Message<?>, List<Location>> closestOrAvailableTrends(
|
||||
TwitterTrendFunctionProperties properties, Twitter twitter) {
|
||||
return message -> {
|
||||
try {
|
||||
if (properties.getClosest().getLat() != null && properties.getClosest().getLon() != null) {
|
||||
double lat = properties.getClosest().getLat().getValue(message, double.class);
|
||||
double lon = properties.getClosest().getLon().getValue(message, double.class);
|
||||
return twitter.getClosestTrends(new GeoLocation(lat, lon));
|
||||
}
|
||||
else {
|
||||
return twitter.getAvailableTrends();
|
||||
}
|
||||
}
|
||||
catch (TwitterException e) {
|
||||
logger.error("Twitter API error!", e);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Function<Message<?>, Message<byte[]>> trendOrTrendLocationsFunction(
|
||||
Function<Object, Message<byte[]>> managedJson, Function<Message<?>, Trends> trend,
|
||||
TwitterTrendFunctionProperties properties, Function<Message<?>,
|
||||
List<Location>> closestOrAvailableTrends) {
|
||||
|
||||
return (properties.getTrendQueryType() == TwitterTrendFunctionProperties.TrendQueryType.trend) ?
|
||||
trend.andThen(managedJson) : closestOrAvailableTrends.andThen(managedJson);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.cloud.fn.twitter.trend;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@ConfigurationProperties("twitter.trend")
|
||||
@Validated
|
||||
public class TwitterTrendFunctionProperties {
|
||||
|
||||
private static final Expression DEFAULT_EXPRESSION = new SpelExpressionParser().parseExpression("payload");
|
||||
|
||||
enum TrendQueryType {
|
||||
/** Retrieve trending places. */
|
||||
trend,
|
||||
/** Retrieve the Locations of trending places. */
|
||||
trendLocation
|
||||
}
|
||||
|
||||
private TrendQueryType trendQueryType = TrendQueryType.trend;
|
||||
|
||||
public TrendQueryType getTrendQueryType() {
|
||||
return trendQueryType;
|
||||
}
|
||||
|
||||
public void setTrendQueryType(TrendQueryType trendQueryType) {
|
||||
this.trendQueryType = trendQueryType;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Yahoo! Where On Earth ID of the location to return trending information for.
|
||||
* Global information is available by using 1 as the WOEID.
|
||||
*/
|
||||
@NotNull
|
||||
private Expression locationId = DEFAULT_EXPRESSION;
|
||||
|
||||
public Expression getLocationId() {
|
||||
return locationId;
|
||||
}
|
||||
|
||||
public void setLocationId(Expression locationId) {
|
||||
this.locationId = locationId;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Closest closest = new Closest();
|
||||
|
||||
public Closest getClosest() {
|
||||
return closest;
|
||||
}
|
||||
|
||||
public static class Closest {
|
||||
/**
|
||||
* If provided with a long parameter the available trend locations will be sorted by distance, nearest
|
||||
* to furthest, to the co-ordinate pair.
|
||||
* The valid ranges for longitude is -180.0 to +180.0 (West is negative, East is positive) inclusive.
|
||||
*/
|
||||
private Expression lat;
|
||||
|
||||
/**
|
||||
* If provided with a lat parameter the available trend locations will be sorted by distance, nearest to
|
||||
* furthest, to the co-ordinate pair. The valid ranges for longitude is -180.0 to +180.0 (West is negative,
|
||||
* East is positive) inclusive.
|
||||
*/
|
||||
private Expression lon;
|
||||
|
||||
public Expression getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public void setLat(Expression lat) {
|
||||
this.lat = lat;
|
||||
}
|
||||
|
||||
public Expression getLon() {
|
||||
return lon;
|
||||
}
|
||||
|
||||
public void setLon(Expression lon) {
|
||||
this.lon = lon;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user