Make spring-twitter-function as auto-config
* Fix Checkstyle violations in this module * Make all the Twitter function auto-configurations as conditional on their specific properties to avoid extra beans not expected in the target application * Fix README respectively
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
* Copyright 2020-2024 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.
|
||||
@@ -27,27 +27,29 @@ import twitter4j.Place;
|
||||
import twitter4j.Twitter;
|
||||
import twitter4j.TwitterException;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Auto-configuration for Twitter Geo function.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnExpression("environment['twitter.geo.search.ip'] != null || (environment['twitter.geo.location.lat'] != null && environment['twitter.geo.location.lon'] != null)")
|
||||
@AutoConfiguration(after = TwitterConnectionConfiguration.class)
|
||||
@EnableConfigurationProperties(TwitterGeoFunctionProperties.class)
|
||||
@Import(TwitterConnectionConfiguration.class)
|
||||
public class TwitterGeoFunctionConfiguration {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(TwitterGeoFunctionConfiguration.class);
|
||||
private static final Log LOGGER = LogFactory.getLog(TwitterGeoFunctionConfiguration.class);
|
||||
|
||||
@Bean
|
||||
public Function<Message<?>, GeoQuery> messageToGeoQueryFunction(TwitterGeoFunctionProperties geoProperties) {
|
||||
return message -> {
|
||||
return (message) -> {
|
||||
String ip = null;
|
||||
if (geoProperties.getSearch().getIp() != null) {
|
||||
ip = geoProperties.getSearch().getIp().getValue(message, String.class);
|
||||
@@ -76,12 +78,12 @@ public class TwitterGeoFunctionConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "twitter.geo.search.type", havingValue = "search", matchIfMissing = true)
|
||||
public Function<GeoQuery, List<Place>> twitterSearchPlacesFunction(Twitter twitter) {
|
||||
return geoQuery -> {
|
||||
return (geoQuery) -> {
|
||||
try {
|
||||
return twitter.searchPlaces(geoQuery);
|
||||
}
|
||||
catch (TwitterException e) {
|
||||
logger.error("Places Search failed!", e);
|
||||
catch (TwitterException ex) {
|
||||
LOGGER.error("Places Search failed!", ex);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -90,12 +92,12 @@ public class TwitterGeoFunctionConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "twitter.geo.search.type", havingValue = "reverse")
|
||||
public Function<GeoQuery, List<Place>> twitterReverseGeocodeFunction(Twitter twitter) {
|
||||
return geoQuery -> {
|
||||
return (geoQuery) -> {
|
||||
try {
|
||||
return twitter.reverseGeoCode(geoQuery);
|
||||
}
|
||||
catch (TwitterException e) {
|
||||
logger.error("Reverse Geocode failed!", e);
|
||||
catch (TwitterException ex) {
|
||||
LOGGER.error("Reverse Geocode failed!", ex);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -105,7 +107,7 @@ public class TwitterGeoFunctionConfiguration {
|
||||
public Function<Message<?>, Message<byte[]>> twitterGeoFunction(Function<Message<?>, GeoQuery> toGeoQuery,
|
||||
Function<GeoQuery, List<Place>> places, Function<Object, Message<byte[]>> managedJson) {
|
||||
|
||||
return toGeoQuery.andThen(places).andThen(managedJson)::apply;
|
||||
return toGeoQuery.andThen(places).andThen(managedJson);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
* Copyright 2020-2024 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.
|
||||
@@ -21,18 +21,17 @@ import jakarta.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;
|
||||
|
||||
/**
|
||||
* Configuration properties for Twitter Geo function.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@ConfigurationProperties("twitter.geo")
|
||||
@Validated
|
||||
public class TwitterGeoFunctionProperties {
|
||||
|
||||
private static final Expression DEFAULT_EXPRESSION = new SpelExpressionParser().parseExpression("payload");
|
||||
|
||||
public enum GeoType {
|
||||
|
||||
/** Geo retrieval type. */
|
||||
@@ -51,9 +50,6 @@ public class TwitterGeoFunctionProperties {
|
||||
*/
|
||||
private Search search = new Search();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Location location = new Location();
|
||||
|
||||
/**
|
||||
@@ -68,7 +64,7 @@ public class TwitterGeoFunctionProperties {
|
||||
* in meters, but it can also take a string that is suffixed with ft to specify feet.
|
||||
* If this is not passed in, then it is assumed to be 0m. If coming from a device, in
|
||||
* practice, this value is whatever accuracy the device has measuring its location
|
||||
* (whether it be coming from a GPS, WiFi triangulation, etc.).
|
||||
* (whether it be coming from a GPS, Wi-Fi triangulation, etc.).
|
||||
*/
|
||||
private String accuracy = null;
|
||||
|
||||
@@ -79,7 +75,7 @@ public class TwitterGeoFunctionProperties {
|
||||
private String granularity = null;
|
||||
|
||||
public Search getSearch() {
|
||||
return search;
|
||||
return this.search;
|
||||
}
|
||||
|
||||
public void setSearch(Search search) {
|
||||
@@ -87,7 +83,7 @@ public class TwitterGeoFunctionProperties {
|
||||
}
|
||||
|
||||
public GeoType getType() {
|
||||
return type;
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setType(GeoType type) {
|
||||
@@ -95,7 +91,7 @@ public class TwitterGeoFunctionProperties {
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
return this.location;
|
||||
}
|
||||
|
||||
public void setLocation(Location location) {
|
||||
@@ -103,7 +99,7 @@ public class TwitterGeoFunctionProperties {
|
||||
}
|
||||
|
||||
public int getMaxResults() {
|
||||
return maxResults;
|
||||
return this.maxResults;
|
||||
}
|
||||
|
||||
public void setMaxResults(int maxResults) {
|
||||
@@ -111,7 +107,7 @@ public class TwitterGeoFunctionProperties {
|
||||
}
|
||||
|
||||
public String getAccuracy() {
|
||||
return accuracy;
|
||||
return this.accuracy;
|
||||
}
|
||||
|
||||
public void setAccuracy(String accuracy) {
|
||||
@@ -119,7 +115,7 @@ public class TwitterGeoFunctionProperties {
|
||||
}
|
||||
|
||||
public String getGranularity() {
|
||||
return granularity;
|
||||
return this.granularity;
|
||||
}
|
||||
|
||||
public void setGranularity(String granularity) {
|
||||
@@ -128,13 +124,12 @@ public class TwitterGeoFunctionProperties {
|
||||
|
||||
@AssertTrue(message = "Either the IP or the Location must be set")
|
||||
public boolean isAtLeastOne() {
|
||||
return this.getSearch().getIp() == null
|
||||
^ (this.getLocation().getLat() == null && this.getLocation().getLon() == null);
|
||||
return getSearch().getIp() == null ^ (getLocation().getLat() == null && getLocation().getLon() == null);
|
||||
}
|
||||
|
||||
@AssertTrue(message = "The IP parameter is applicable only for 'Search' GeoType")
|
||||
public boolean isIpUsedWithSearchGeoType() {
|
||||
if (this.getSearch().getIp() != null) {
|
||||
if (getSearch().getIp() != null) {
|
||||
return this.type == GeoType.search;
|
||||
}
|
||||
return true;
|
||||
@@ -154,7 +149,7 @@ public class TwitterGeoFunctionProperties {
|
||||
private Expression query = null;
|
||||
|
||||
public Expression getIp() {
|
||||
return ip;
|
||||
return this.ip;
|
||||
}
|
||||
|
||||
public void setIp(Expression ip) {
|
||||
@@ -162,7 +157,7 @@ public class TwitterGeoFunctionProperties {
|
||||
}
|
||||
|
||||
public Expression getQuery() {
|
||||
return query;
|
||||
return this.query;
|
||||
}
|
||||
|
||||
public void setQuery(Expression query) {
|
||||
@@ -184,7 +179,7 @@ public class TwitterGeoFunctionProperties {
|
||||
private Expression lon;
|
||||
|
||||
public Expression getLat() {
|
||||
return lat;
|
||||
return this.lat;
|
||||
}
|
||||
|
||||
public void setLat(Expression lat) {
|
||||
@@ -192,7 +187,7 @@ public class TwitterGeoFunctionProperties {
|
||||
}
|
||||
|
||||
public Expression getLon() {
|
||||
return lon;
|
||||
return this.lon;
|
||||
}
|
||||
|
||||
public void setLon(Expression lon) {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* The Twitter Geo function auto-configuration.
|
||||
*/
|
||||
package org.springframework.cloud.fn.twitter.geo;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
* Copyright 2020-2024 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.
|
||||
@@ -27,32 +27,34 @@ import twitter4j.Trends;
|
||||
import twitter4j.Twitter;
|
||||
import twitter4j.TwitterException;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Auto-configuration for Twitter Trend function.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "twitter.trend", name = "trend-query-type")
|
||||
@AutoConfiguration(after = TwitterConnectionConfiguration.class)
|
||||
@EnableConfigurationProperties(TwitterTrendFunctionProperties.class)
|
||||
@Import(TwitterConnectionConfiguration.class)
|
||||
public class TwitterTrendFunctionConfiguration {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(TwitterTrendFunctionConfiguration.class);
|
||||
private static final Log LOGGER = LogFactory.getLog(TwitterTrendFunctionConfiguration.class);
|
||||
|
||||
@Bean
|
||||
public Function<Message<?>, Trends> trend(TwitterTrendFunctionProperties properties, Twitter twitter) {
|
||||
return message -> {
|
||||
return (message) -> {
|
||||
try {
|
||||
int woeid = properties.getLocationId().getValue(message, int.class);
|
||||
return twitter.getPlaceTrends(woeid);
|
||||
}
|
||||
catch (TwitterException e) {
|
||||
logger.error("Twitter API error!", e);
|
||||
catch (TwitterException ex) {
|
||||
LOGGER.error("Twitter API error!", ex);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -61,7 +63,8 @@ public class TwitterTrendFunctionConfiguration {
|
||||
@Bean
|
||||
public Function<Message<?>, List<Location>> closestOrAvailableTrends(TwitterTrendFunctionProperties properties,
|
||||
Twitter twitter) {
|
||||
return message -> {
|
||||
|
||||
return (message) -> {
|
||||
try {
|
||||
if (properties.getClosest().getLat() != null && properties.getClosest().getLon() != null) {
|
||||
double lat = properties.getClosest().getLat().getValue(message, double.class);
|
||||
@@ -72,8 +75,8 @@ public class TwitterTrendFunctionConfiguration {
|
||||
return twitter.getAvailableTrends();
|
||||
}
|
||||
}
|
||||
catch (TwitterException e) {
|
||||
logger.error("Twitter API error!", e);
|
||||
catch (TwitterException ex) {
|
||||
LOGGER.error("Twitter API error!", ex);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
* Copyright 2020-2024 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.
|
||||
@@ -20,19 +20,22 @@ import jakarta.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.integration.expression.FunctionExpression;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
* Configuration properties for Twitter Trend function.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@ConfigurationProperties("twitter.trend")
|
||||
@Validated
|
||||
public class TwitterTrendFunctionProperties {
|
||||
|
||||
private static final Expression DEFAULT_EXPRESSION = new SpelExpressionParser().parseExpression("payload");
|
||||
private static final Expression DEFAULT_EXPRESSION = new FunctionExpression<Message<?>>(Message::getPayload);
|
||||
|
||||
enum TrendQueryType {
|
||||
public enum TrendQueryType {
|
||||
|
||||
/** Retrieve trending places. */
|
||||
trend,
|
||||
@@ -41,10 +44,10 @@ public class TwitterTrendFunctionProperties {
|
||||
|
||||
}
|
||||
|
||||
private TrendQueryType trendQueryType = TrendQueryType.trend;
|
||||
private TrendQueryType trendQueryType;
|
||||
|
||||
public TrendQueryType getTrendQueryType() {
|
||||
return trendQueryType;
|
||||
return this.trendQueryType;
|
||||
}
|
||||
|
||||
public void setTrendQueryType(TrendQueryType trendQueryType) {
|
||||
@@ -59,40 +62,39 @@ public class TwitterTrendFunctionProperties {
|
||||
private Expression locationId = DEFAULT_EXPRESSION;
|
||||
|
||||
public Expression getLocationId() {
|
||||
return locationId;
|
||||
return this.locationId;
|
||||
}
|
||||
|
||||
public void setLocationId(Expression locationId) {
|
||||
this.locationId = locationId;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Closest closest = new Closest();
|
||||
private final Closest closest = new Closest();
|
||||
|
||||
public Closest getClosest() {
|
||||
return closest;
|
||||
return this.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.
|
||||
* by distance, nearest to the 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.
|
||||
* by distance, nearest to the 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;
|
||||
return this.lat;
|
||||
}
|
||||
|
||||
public void setLat(Expression lat) {
|
||||
@@ -100,7 +102,7 @@ public class TwitterTrendFunctionProperties {
|
||||
}
|
||||
|
||||
public Expression getLon() {
|
||||
return lon;
|
||||
return this.lon;
|
||||
}
|
||||
|
||||
public void setLon(Expression lon) {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* The Twitter Trend function auto-configuration.
|
||||
*/
|
||||
package org.springframework.cloud.fn.twitter.trend;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
* Copyright 2020-2024 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.
|
||||
@@ -21,41 +21,40 @@ import java.util.function.Function;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import twitter4j.ResponseList;
|
||||
import twitter4j.Twitter;
|
||||
import twitter4j.TwitterException;
|
||||
import twitter4j.User;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Auto-configuration for Twitter Users function.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "twitter.users", name = "type")
|
||||
@AutoConfiguration(after = TwitterConnectionConfiguration.class)
|
||||
@EnableConfigurationProperties(TwitterUsersFunctionProperties.class)
|
||||
@Import(TwitterConnectionConfiguration.class)
|
||||
public class TwitterUsersFunctionConfiguration {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(TwitterUsersFunctionConfiguration.class);
|
||||
private static final Log LOGGER = LogFactory.getLog(TwitterUsersFunctionConfiguration.class);
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "twitter.users.type", havingValue = "search")
|
||||
public Function<Message<?>, List<User>> userSearch(Twitter twitter, TwitterUsersFunctionProperties properties) {
|
||||
|
||||
return message -> {
|
||||
return (message) -> {
|
||||
String query = properties.getSearch().getQuery().getValue(message, String.class);
|
||||
try {
|
||||
ResponseList<User> users = twitter.searchUsers(query, properties.getSearch().getPage());
|
||||
return users;
|
||||
return twitter.searchUsers(query, properties.getSearch().getPage());
|
||||
}
|
||||
catch (TwitterException e) {
|
||||
logger.error("Twitter API error!", e);
|
||||
catch (TwitterException ex) {
|
||||
LOGGER.error("Twitter API error!", ex);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -65,7 +64,7 @@ public class TwitterUsersFunctionConfiguration {
|
||||
@ConditionalOnProperty(name = "twitter.users.type", havingValue = "lookup")
|
||||
public Function<Message<?>, List<User>> userLookup(Twitter twitter, TwitterUsersFunctionProperties properties) {
|
||||
|
||||
return message -> {
|
||||
return (message) -> {
|
||||
|
||||
try {
|
||||
TwitterUsersFunctionProperties.Lookup lookup = properties.getLookup();
|
||||
@@ -78,20 +77,17 @@ public class TwitterUsersFunctionConfiguration {
|
||||
return twitter.lookupUsers(ids);
|
||||
}
|
||||
}
|
||||
catch (TwitterException e) {
|
||||
logger.error("Twitter API error!", e);
|
||||
catch (TwitterException ex) {
|
||||
LOGGER.error("Twitter API error!", ex);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
/**
|
||||
* queryUsers - depends on the `twitter.users.type` property is either userSearch or
|
||||
* userLookup. managedJson - converts Users into JSON message payload.
|
||||
*/
|
||||
public Function<Message<?>, Message<byte[]>> twitterUsersFunction(Function<Message<?>, List<User>> queryUsers,
|
||||
Function<Object, Message<byte[]>> managedJson) {
|
||||
|
||||
return queryUsers.andThen(managedJson);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
* Copyright 2020-2024 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.
|
||||
@@ -17,21 +17,23 @@
|
||||
package org.springframework.cloud.fn.twitter.users;
|
||||
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.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.integration.expression.FunctionExpression;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
* Configuration properties for Twitter Users function.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@ConfigurationProperties("twitter.users")
|
||||
@Validated
|
||||
public class TwitterUsersFunctionProperties {
|
||||
|
||||
private static final Expression DEFAULT_EXPRESSION = new SpelExpressionParser().parseExpression("payload");
|
||||
private static final Expression DEFAULT_EXPRESSION = new FunctionExpression<Message<?>>(Message::getPayload);
|
||||
|
||||
public enum UserQueryType {
|
||||
|
||||
@@ -43,8 +45,7 @@ public class TwitterUsersFunctionProperties {
|
||||
/**
|
||||
* Perform search or lookup type of search.
|
||||
*/
|
||||
@NotNull
|
||||
private UserQueryType type = UserQueryType.search;
|
||||
private UserQueryType type;
|
||||
|
||||
/**
|
||||
* Returns fully-hydrated user objects for specified by comma-separated values passed
|
||||
@@ -53,13 +54,13 @@ public class TwitterUsersFunctionProperties {
|
||||
private final Lookup lookup = new Lookup();
|
||||
|
||||
/**
|
||||
* relevance-based search interface for querying by topical interest, full name,
|
||||
* Relevance-based search interface for querying by topical interest, full name,
|
||||
* company name, location, or other criteria.
|
||||
*/
|
||||
private final Search search = new Search();
|
||||
|
||||
public UserQueryType getType() {
|
||||
return type;
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setType(UserQueryType type) {
|
||||
@@ -67,20 +68,20 @@ public class TwitterUsersFunctionProperties {
|
||||
}
|
||||
|
||||
public Lookup getLookup() {
|
||||
return lookup;
|
||||
return this.lookup;
|
||||
}
|
||||
|
||||
public Search getSearch() {
|
||||
return search;
|
||||
return this.search;
|
||||
}
|
||||
|
||||
@AssertTrue(message = "Per query type validate the required parameters")
|
||||
public boolean checkParametersPerType() {
|
||||
if (this.getType() == UserQueryType.lookup) {
|
||||
return (this.getLookup().getScreenName() != null) || (this.getLookup().getUserId() != null);
|
||||
if (getType() == UserQueryType.lookup) {
|
||||
return (getLookup().getScreenName() != null) || (getLookup().getUserId() != null);
|
||||
}
|
||||
else if (this.getType() == UserQueryType.search) {
|
||||
return (this.getSearch().getQuery() != null);
|
||||
else if (getType() == UserQueryType.search) {
|
||||
return (getSearch().getQuery() != null);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -102,7 +103,7 @@ public class TwitterUsersFunctionProperties {
|
||||
private Expression screenName;
|
||||
|
||||
public Expression getUserId() {
|
||||
return userId;
|
||||
return this.userId;
|
||||
}
|
||||
|
||||
public void setUserId(Expression userId) {
|
||||
@@ -110,7 +111,7 @@ public class TwitterUsersFunctionProperties {
|
||||
}
|
||||
|
||||
public Expression getScreenName() {
|
||||
return screenName;
|
||||
return this.screenName;
|
||||
}
|
||||
|
||||
public void setScreenName(Expression screenName) {
|
||||
@@ -132,7 +133,7 @@ public class TwitterUsersFunctionProperties {
|
||||
private int page = 3;
|
||||
|
||||
public Expression getQuery() {
|
||||
return query;
|
||||
return this.query;
|
||||
}
|
||||
|
||||
public void setQuery(Expression query) {
|
||||
@@ -140,7 +141,7 @@ public class TwitterUsersFunctionProperties {
|
||||
}
|
||||
|
||||
public int getPage() {
|
||||
return page;
|
||||
return this.page;
|
||||
}
|
||||
|
||||
public void setPage(int page) {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* The Twitter Users function auto-configuration.
|
||||
*/
|
||||
package org.springframework.cloud.fn.twitter.users;
|
||||
@@ -0,0 +1,3 @@
|
||||
org.springframework.cloud.fn.twitter.geo.TwitterGeoFunctionConfiguration
|
||||
org.springframework.cloud.fn.twitter.trend.TwitterTrendFunctionConfiguration
|
||||
org.springframework.cloud.fn.twitter.users.TwitterUsersFunctionConfiguration
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
* Copyright 2020-2024 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.
|
||||
@@ -40,13 +40,11 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.fn.common.twitter.TwitterConnectionProperties;
|
||||
import org.springframework.cloud.fn.common.twitter.util.TwitterTestUtils;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.util.TestSocketUtils;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -58,17 +56,14 @@ import static org.mockserver.verify.VerificationTimes.once;
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
|
||||
properties = { "twitter.connection.consumerKey=consumerKey666",
|
||||
"twitter.connection.consumerSecret=consumerSecret666", "twitter.connection.accessToken=accessToken666",
|
||||
"twitter.connection.accessTokenSecret=accessTokenSecret666" })
|
||||
@SpringBootTest(properties = { "twitter.connection.consumerKey=consumerKey666",
|
||||
"twitter.connection.consumerSecret=consumerSecret666", "twitter.connection.accessToken=accessToken666",
|
||||
"twitter.connection.accessTokenSecret=accessTokenSecret666" })
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
|
||||
public abstract class TwitterGeoFunctionTest {
|
||||
public abstract class TwitterGeoFunctionTests {
|
||||
|
||||
private static final String MOCK_SERVER_IP = "127.0.0.1";
|
||||
|
||||
private static final Integer MOCK_SERVER_PORT = TestSocketUtils.findAvailableTcpPort();
|
||||
|
||||
private static ClientAndServer mockServer;
|
||||
|
||||
private static MockServerClient mockClient;
|
||||
@@ -90,8 +85,8 @@ public abstract class TwitterGeoFunctionTest {
|
||||
|
||||
@BeforeAll
|
||||
public static void startMockServer() {
|
||||
mockServer = ClientAndServer.startClientAndServer(MOCK_SERVER_PORT);
|
||||
mockClient = new MockServerClient(MOCK_SERVER_IP, MOCK_SERVER_PORT);
|
||||
mockServer = ClientAndServer.startClientAndServer();
|
||||
mockClient = new MockServerClient(MOCK_SERVER_IP, mockServer.getPort());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
@@ -101,7 +96,7 @@ public abstract class TwitterGeoFunctionTest {
|
||||
|
||||
@TestPropertySource(
|
||||
properties = { "twitter.geo.search.ip='127.0.0.1'", "twitter.geo.search.query=payload.toUpperCase()" })
|
||||
public static class TwitterGeoSearchByIPAndQueryTests extends TwitterGeoFunctionTest {
|
||||
public static class TwitterGeoSearchByIPAndQueryTests extends TwitterGeoFunctionTests {
|
||||
|
||||
@Test
|
||||
public void testOne() throws IOException {
|
||||
@@ -125,7 +120,7 @@ public abstract class TwitterGeoFunctionTest {
|
||||
|
||||
assertThat(outPayload).isNotNull();
|
||||
|
||||
List places = new ObjectMapper().readValue(outPayload, List.class);
|
||||
List<?> places = new ObjectMapper().readValue(outPayload, List.class);
|
||||
assertThat(places).hasSize(12);
|
||||
}
|
||||
|
||||
@@ -133,7 +128,7 @@ public abstract class TwitterGeoFunctionTest {
|
||||
|
||||
@TestPropertySource(properties = { "twitter.geo.location.lat='52.378'", "twitter.geo.location.lon='4.9'",
|
||||
"twitter.geo.search.query=payload.toUpperCase()" })
|
||||
public static class TwitterGeoSearchByLocationTests extends TwitterGeoFunctionTest {
|
||||
public static class TwitterGeoSearchByLocationTests extends TwitterGeoFunctionTests {
|
||||
|
||||
@Test
|
||||
public void testOne() throws IOException {
|
||||
@@ -159,7 +154,7 @@ public abstract class TwitterGeoFunctionTest {
|
||||
|
||||
assertThat(outPayload).isNotNull();
|
||||
|
||||
List places = new ObjectMapper().readValue(outPayload, List.class);
|
||||
List<?> places = new ObjectMapper().readValue(outPayload, List.class);
|
||||
assertThat(places).hasSize(12);
|
||||
}
|
||||
|
||||
@@ -167,7 +162,7 @@ public abstract class TwitterGeoFunctionTest {
|
||||
|
||||
@TestPropertySource(properties = { "twitter.geo.type=reverse", "twitter.geo.location.lat='52.378'",
|
||||
"twitter.geo.location.lon='4.9'" })
|
||||
public static class TwitterGeoSearchByLocation2Tests extends TwitterGeoFunctionTest {
|
||||
public static class TwitterGeoSearchByLocation2Tests extends TwitterGeoFunctionTests {
|
||||
|
||||
@Test
|
||||
public void testOne() throws IOException {
|
||||
@@ -191,7 +186,7 @@ public abstract class TwitterGeoFunctionTest {
|
||||
|
||||
assertThat(outPayload).isNotNull();
|
||||
|
||||
List places = new ObjectMapper().readValue(outPayload, List.class);
|
||||
List<?> places = new ObjectMapper().readValue(outPayload, List.class);
|
||||
assertThat(places).hasSize(12);
|
||||
}
|
||||
|
||||
@@ -200,7 +195,7 @@ public abstract class TwitterGeoFunctionTest {
|
||||
@TestPropertySource(properties = { "twitter.geo.location.lat=#jsonPath(new String(payload),'$.location.lat')",
|
||||
"twitter.geo.location.lon=#jsonPath(new String(payload),'$.location.lon')",
|
||||
"twitter.geo.search.query=#jsonPath(new String(payload),'$.country')" })
|
||||
public static class TwitterGeoSearchJsonPathTests extends TwitterGeoFunctionTest {
|
||||
public static class TwitterGeoSearchJsonPathTests extends TwitterGeoFunctionTests {
|
||||
|
||||
@Test
|
||||
public void testOne() throws IOException {
|
||||
@@ -228,7 +223,7 @@ public abstract class TwitterGeoFunctionTest {
|
||||
|
||||
assertThat(outPayload).isNotNull();
|
||||
|
||||
List places = new ObjectMapper().readValue(outPayload, List.class);
|
||||
List<?> places = new ObjectMapper().readValue(outPayload, List.class);
|
||||
assertThat(places).hasSize(12);
|
||||
}
|
||||
|
||||
@@ -236,7 +231,6 @@ public abstract class TwitterGeoFunctionTest {
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@Import(TwitterGeoFunctionConfiguration.class)
|
||||
public static class TwitterGeoFunctionTestApplication {
|
||||
|
||||
@Bean
|
||||
@@ -246,7 +240,7 @@ public abstract class TwitterGeoFunctionTest {
|
||||
|
||||
Function<TwitterConnectionProperties, ConfigurationBuilder> mockedConfiguration = toConfigurationBuilder
|
||||
.andThen(new TwitterTestUtils()
|
||||
.mockTwitterUrls(String.format("http://%s:%s", MOCK_SERVER_IP, MOCK_SERVER_PORT)));
|
||||
.mockTwitterUrls(String.format("http://%s:%s", MOCK_SERVER_IP, mockServer.getPort())));
|
||||
|
||||
return mockedConfiguration.apply(properties).build();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
* Copyright 2020-2024 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.
|
||||
@@ -35,13 +35,11 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.fn.common.twitter.TwitterConnectionProperties;
|
||||
import org.springframework.cloud.fn.common.twitter.util.TwitterTestUtils;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.util.TestSocketUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockserver.matchers.Times.exactly;
|
||||
@@ -61,8 +59,6 @@ public abstract class TwitterTrendFunctionTests {
|
||||
|
||||
private static final String MOCK_SERVER_IP = "127.0.0.1";
|
||||
|
||||
private static final Integer MOCK_SERVER_PORT = TestSocketUtils.findAvailableTcpPort();
|
||||
|
||||
private static ClientAndServer mockServer;
|
||||
|
||||
private static MockServerClient mockClient;
|
||||
@@ -74,8 +70,8 @@ public abstract class TwitterTrendFunctionTests {
|
||||
|
||||
@BeforeAll
|
||||
public static void startServer() {
|
||||
mockServer = ClientAndServer.startClientAndServer(MOCK_SERVER_PORT);
|
||||
mockClient = new MockServerClient(MOCK_SERVER_IP, MOCK_SERVER_PORT);
|
||||
mockServer = ClientAndServer.startClientAndServer();
|
||||
mockClient = new MockServerClient(MOCK_SERVER_IP, mockServer.getPort());
|
||||
|
||||
trendsRequest = setExpectation(
|
||||
request().withMethod("GET").withPath("/trends/place.json").withQueryStringParameter("id", "2972"));
|
||||
@@ -96,7 +92,8 @@ public abstract class TwitterTrendFunctionTests {
|
||||
return request;
|
||||
}
|
||||
|
||||
@TestPropertySource(properties = { "twitter.trend.locationId='2972'", "twitter.connection.rawJson=true" })
|
||||
@TestPropertySource(properties = { "twitter.trend.trendQueryType=trend", "twitter.trend.locationId='2972'",
|
||||
"twitter.connection.rawJson=true" })
|
||||
public static class TwitterTrendPayloadTests extends TwitterTrendFunctionTests {
|
||||
|
||||
@Test
|
||||
@@ -110,7 +107,6 @@ public abstract class TwitterTrendFunctionTests {
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@Import(TwitterTrendFunctionConfiguration.class)
|
||||
public static class TwitterTrendFunctionTestApplication {
|
||||
|
||||
@Bean
|
||||
@@ -120,7 +116,7 @@ public abstract class TwitterTrendFunctionTests {
|
||||
|
||||
Function<TwitterConnectionProperties, ConfigurationBuilder> mockedConfiguration = toConfigurationBuilder
|
||||
.andThen(new TwitterTestUtils()
|
||||
.mockTwitterUrls(String.format("http://%s:%s", MOCK_SERVER_IP, MOCK_SERVER_PORT)));
|
||||
.mockTwitterUrls(String.format("http://%s:%s", MOCK_SERVER_IP, mockServer.getPort())));
|
||||
|
||||
return mockedConfiguration.apply(properties).build();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
* Copyright 2020-2024 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.
|
||||
@@ -38,13 +38,11 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.fn.common.twitter.TwitterConnectionProperties;
|
||||
import org.springframework.cloud.fn.common.twitter.util.TwitterTestUtils;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.util.TestSocketUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockserver.matchers.Times.exactly;
|
||||
@@ -64,8 +62,6 @@ public abstract class TwitterUsersFunctionTests {
|
||||
|
||||
private static final String MOCK_SERVER_IP = "127.0.0.1";
|
||||
|
||||
private static final Integer MOCK_SERVER_PORT = TestSocketUtils.findAvailableTcpPort();
|
||||
|
||||
private static ClientAndServer mockServer;
|
||||
|
||||
private static MockServerClient mockClient;
|
||||
@@ -94,8 +90,8 @@ public abstract class TwitterUsersFunctionTests {
|
||||
|
||||
@BeforeAll
|
||||
public static void startServer() {
|
||||
mockServer = ClientAndServer.startClientAndServer(MOCK_SERVER_PORT);
|
||||
mockClient = new MockServerClient(MOCK_SERVER_IP, MOCK_SERVER_PORT);
|
||||
mockServer = ClientAndServer.startClientAndServer();
|
||||
mockClient = new MockServerClient(MOCK_SERVER_IP, mockServer.getPort());
|
||||
|
||||
searchUsersRequest = setExpectation(request().withMethod("GET")
|
||||
.withPath("/users/search.json")
|
||||
@@ -127,7 +123,7 @@ public abstract class TwitterUsersFunctionTests {
|
||||
Message<?> received = twitterUsersFunction.apply(MessageBuilder.withPayload("tzolov").build());
|
||||
mockClient.verify(searchUsersRequest, once());
|
||||
assertThat(received).isNotNull();
|
||||
List list = mapper.readValue(new String((byte[]) received.getPayload()), List.class);
|
||||
List<?> list = mapper.readValue(new String((byte[]) received.getPayload()), List.class);
|
||||
assertThat(list).hasSize(20);
|
||||
}
|
||||
|
||||
@@ -144,7 +140,7 @@ public abstract class TwitterUsersFunctionTests {
|
||||
|
||||
mockClient.verify(lookupUsersRequest, once());
|
||||
assertThat(received).isNotNull();
|
||||
List list = mapper.readValue(new String((byte[]) received.getPayload()), List.class);
|
||||
List<?> list = mapper.readValue(new String((byte[]) received.getPayload()), List.class);
|
||||
assertThat(list).hasSize(5);
|
||||
}
|
||||
|
||||
@@ -164,7 +160,7 @@ public abstract class TwitterUsersFunctionTests {
|
||||
|
||||
mockClient.verify(lookupUsersRequest2, once());
|
||||
assertThat(received).isNotNull();
|
||||
List list = mapper.readValue(new String((byte[]) received.getPayload()), List.class);
|
||||
List<?> list = mapper.readValue(new String((byte[]) received.getPayload()), List.class);
|
||||
assertThat(list).hasSize(5);
|
||||
}
|
||||
|
||||
@@ -172,17 +168,16 @@ public abstract class TwitterUsersFunctionTests {
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@Import(TwitterUsersFunctionConfiguration.class)
|
||||
static class TwitterUsersFunctionTestApplication {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public twitter4j.conf.Configuration twitterConfiguration2(TwitterConnectionProperties properties,
|
||||
twitter4j.conf.Configuration twitterConfiguration2(TwitterConnectionProperties properties,
|
||||
Function<TwitterConnectionProperties, ConfigurationBuilder> toConfigurationBuilder) {
|
||||
|
||||
Function<TwitterConnectionProperties, ConfigurationBuilder> mockedConfiguration = toConfigurationBuilder
|
||||
.andThen(new TwitterTestUtils()
|
||||
.mockTwitterUrls(String.format("http://%s:%s", MOCK_SERVER_IP, MOCK_SERVER_PORT)));
|
||||
.mockTwitterUrls(String.format("http://%s:%s", MOCK_SERVER_IP, mockServer.getPort())));
|
||||
|
||||
return mockedConfiguration.apply(properties).build();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user