convertAndSendToUser() metodu ile belirli bir kullanıcıya mesaj gönderir.
convertAndSend metodu ile tüm kullanıcılara mesaj gönderir.
- The text datatype is used for full-text search and any field mapped as text gets converted into individual words before being indexed.- The keyword datatype is used for exact matches. The field doesn’t get analyzed and gets stored as it is.- Elasticsearch has removed the string datatype in versions 5.0 and above and introduced two new datatypes text and keyword. Any string field gets analyzed with both these datatypes. However you can modify the behavior.
Şöyle yaparızimport com.fasterxml.jackson.annotation.JsonProperty;import org.springframework.data.annotation.Id;import org.springframework.data.elasticsearch.annotations.Document;import org.springframework.data.elasticsearch.annotations.Field;import org.springframework.data.elasticsearch.annotations.FieldType;@Document(indexName = "foo_message")public class Foo {@Id@Field(type = FieldType.Keyword)@JsonProperty("id")public String id;@JsonProperty("message")public String message;@JsonProperty("senderUsername")public String senderUsername;@JsonProperty("senderUserId")public Long senderUserId;@JsonProperty("receiverUserId")public Long receiverUserId;}
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;import org.springframework.stereotype.Repository;@Repositorypublic interface KafkaMessageRepository extends ElasticsearchRepository<Foo, String> {List<Foo> findAllBySenderUserIdAndReceiverUserIdOrderById(Long senderId, Long receiverId);}
@Document(indexName = "productindex")public class Product {@Idprivate String id;@Field(type = FieldType.Text, name = "name")private String name;@Field(type = FieldType.Double, name = "price")private Double price;@Field(type = FieldType.Integer, name = "quantity")private Integer quantity;@Field(type = FieldType.Keyword, name = "category")private String category;@Field(type = FieldType.Text, name = "desc")private String description;@Field(type = FieldType.Keyword, name = "manufacturer")private String manufacturer;...}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Document(indexName = "book")
public class Book {
@Id
private String id;
@Field(type = FieldType.Text, name = "title")
private String title;
@Field(type = FieldType.Integer, name = "page")
private Integer page;
@Field(type = FieldType.Text, name = "isbn")
private String isbn;
@Field(type = FieldType.Text, name = "description")
private String description;
@Field(type = FieldType.Text, name = "language")
private String language;
@Field(type = FieldType.Double, name = "price")
private Double price;
}Açıklaması şöyle@Document(indexName = "blog", type = "article")public class Article {@Idprivate String id;private String title;@Field(type = FieldType.Nested, includeInParent = true)private List<Author> authors;// standard getters and setters}
The authors field is marked as FieldType.Nested. This allows us to define the Author class separately, but have the individual instances of author embedded in an Article document when it is indexed in Elasticsearch.
public class Author {@Field(type = Text)private String name;...}
- Rich set of predicate and filter support — provides various predicates like: path, cookie, time, header, host, method, query, remote address, weight etc. Similar to predicates, it provide number of filters like: Add/Set/Remove/Map Request/Response Headers, Set response code, Redirect, Rewrite etc. filters- Circuit breakers — supports circuit-breakers based on time and re-direct on failure- TLS & SSL — TLS and SSL can be configured for Gateway and httpClient inside the Gateway- Route Metadata — Routes can be configured with metadata which further can be utilized for processing- Easy integration with discovery service and load balancing- Easy metrics with Actuator- Easy cache implementation
The routing configuration can be created by using pure Java (RouteLocator) or by using properties configuration
However Zuul is a blocking API. A blocking gateway api makes use of as many threads as the number of incoming requests. So this approach is more resource intensive. If no threads are available to process incoming request then the request has to wait in queue....Spring Cloud Gateway is a non blocking API. When using non blocking API, a thread is always available to process the incoming request. These request are then processed asynchronously in the background and once completed the response is returned. So no incoming request never gets blocked when using Spring Cloud Gateway.
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
Route: Think of this as the destination that we want a particular request to route to. It comprises of destination URI, a condition that has to satisfy — Or in terms of technical terms, Predicates, and one or more filters.Predicate: This is literally a condition to match. i.e. kind of “if” condition..if requests has something — e.g. path=blah or request header contains foo-bar etc. In technical terms, it is Java 8 Function PredicateFilter: These are instances of Spring Framework WebFilter. This is where you can apply your magic of modifying request or response. There are quite a lot of out of box WebFilter that framework provides. But of course, we are talking about Spring Framework. So, rest easy folks!!! You can always add your own filter with your own logic :)
- Route: Route the basic building block of the gateway. It consists of- ID- destination URI- Collection of predicates and a collection of filters- A route is matched if aggregate predicate is true.- Predicate: This is similar to Java 8 Function Predicate. Using this functionality we can match HTTP request, such as headers , url, cookies or parameters.- Filter: These are instances Spring Framework GatewayFilter. Using this we can modify the request or response as per the requirement.
Applies to all the routes but not the controllers hosted in the gateway. Spring provides many inbuilt filters for normal use cases and if required we can implement custom filters as well.For example, we can apply an inbuilt filter ‘AddRequestHeader’ that adds the header ‘request-header’ in all requests with the value ‘request-header-value’ in the following way://Apply filter for all routes using springs inbuilt filter //"AddRequestHeader"spring.cloud.gateway.default-filters[0]=AddRequestHeader=request-header, request-header-value
For configuring specific routes, we can apply a route-specific filter in the following way:
Applies to all routes as well as the controllers defined in the gateway by us. We need to implement the WebFilter interface in our custom filter and then write our custom logic by overriding the filter() method
@Component
@Slf4j
public class CustomFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
log.trace("inside custom filter");
ServerHttpRequest request = exchange.getRequest();
// logic for request validation
return chain.filter(exchange);
}
}There are 2 different types of filters.Pre Filters — if you want to add or change request object before you pass it down to destination service, you can use these filters.Post Filters — if you want to add or change response object before you pass it back to client, you can use these filters.
- Zuul is the front door for all requests from devices and web sites to the backend of the Netflix streaming application.- Zuul will serve as our API gateway- Handle dynamic routing- Zuul is built to enable dynamic routing, monitoring, resiliency and security.
Spring Cloud no longer supports Netflix Zuul.
Zuul has mainly four types of filters that enable us to intercept the traffic in different timelines of the request processing for any particular transaction. We can add any number of filters for a particular URL pattern.1. pre-filters — are invoked before the request is routed2. post-filers — are invoked after the request has been routed3. route-filters — are used to route the request4. error-filters — are invoked when an error occurs while handling the request.
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency>,
public interface UserRepository extends JpaRepository<User, Long> {
}public void updateUser(int id, String name, int changeReqId){
User mUser = userRepository.findOne(id); //1
mUser.setName(name); //2
ChangeRequest cr = changeRequestRepository.findOne(changeReqId);
ChangeResponse rs = userWebService.updateDetails(mUser); //3
if(rs.isAccepted()){
userRepository.saveAndFlush(mUser); //4
}
cr.setResponseCode(rs.getCode());
changeRequestRepository.saveAndFlush(cr); //this call also saves the changes at step 2
}public interface UserRepositoryCustom {
...
void detachUser(User u);
...
}
public interface UserRepository extends JpaRepository<User, Long>, UserRepositoryCustom {
...
}
@Repository
public class UserRepositoryCustomImpl implements UserRepositoryCustom {
...
@PersistenceContext
private EntityManager entityManager;
@Override
public void detachUser(User u) {
entityManager.detach(u);
}
...
}JdbcTemplate allows us to translate the SQL result directly into an object or a list of objects by using the RowMapper or ResultSetExtractor interface.
public <T> T query(final String sql, final ResultSetExtractor<T> rse)jdbcTemplate.query(
"SELECT id, name, email FROM users",
(rs, rowNum) -> new User(rs.getLong("id"), rs.getString("name"), rs.getString("email"))
).forEach(user -> System.out.println(user.getName()));@Deprecated
@Override
@Nullable
public <T> T query(String sql, @Nullable Object[] args, ResultSetExtractor<T> rse)List<Foo> list =
fdbcTemplate.query(sql, mapParameters, new ResultSetExtractor<List<DataList>>() {
@Override
public List<Foo> extractData(ResultSet r) throws SQLException, DataAccessException {
List<Foo> list = new ArrayList<Foo>();
Foo foo = null;
while(r.next()) {
foo = new Foo();
foo.setName(r.getString("cName"));
list.add(foo);
}
return list;
}
});