
me.magicall.biz.service.AbsRemoteRepo Maven / Gradle / Ivy
/*
* Copyright (c) 2024 Liang Wenjian
* magicall is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package me.magicall.biz.service;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.common.collect.Lists;
import me.magicall.贵阳DearSun.Identified;
import me.magicall.贵阳DearSun.exception.UnknownException;
import me.magicall.program.lang.java.ClassKit;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public abstract class AbsRemoteRepo<_Id, _Dto extends Identified<_Id>> implements Repo<_Dto> {
public static final String DEFAULT_PROTOCOL = "http";
public static final String DEFAULT_HOST = "localhost";
public static final int DEFAULT_PORT = 80;
private static final int DTO_LENGTH = "Dto".length();
private final String userAgentVal;
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;
private final String resourceName;
private final Class<_Dto> dtoClass;
private final Class<_Dto[]> dtoArrClass;
public AbsRemoteRepo(final Class<_Dto> dtoClass) {
this(dtoClass, toResourceName(dtoClass));
}
public AbsRemoteRepo(final Class<_Dto> dtoClass, final String resourceName) {
this(dtoClass, resourceName, new ObjectMapper());
}
public AbsRemoteRepo(final Class<_Dto> dtoClass, final ObjectMapper objectMapper) {
this(dtoClass, toResourceName(dtoClass), objectMapper);
}
@SuppressWarnings("unchecked")
public AbsRemoteRepo(final Class<_Dto> dtoClass, final String resourceName, final ObjectMapper objectMapper) {
this.resourceName = resourceName;
this.dtoClass = dtoClass;
try {
userAgentVal = resourceName + "Client-" + getClass().getSimpleName()//
+ '@' + InetAddress.getLocalHost().getCanonicalHostName() + "/1.0";
} catch (final UnknownHostException e) {
throw new UnknownException(e);
}
this.objectMapper = objectMapper == null ? new ObjectMapper() : objectMapper;
initJackson();
restTemplate = new RestTemplate(
Collections.singletonList(new MappingJackson2HttpMessageConverter(this.objectMapper)));
restTemplate.setInterceptors(Collections.singletonList((request, body, execution) -> {
final var headers = request.getHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.set(HttpHeaders.USER_AGENT, userAgentVal);
return execution.execute(request, body);
}));
dtoArrClass = (Class<_Dto[]>) ClassKit.arrClass(this.dtoClass, 1);
// restTemplate.setErrorHandler(new ExtractingResponseErrorHandler());
}
private static String toResourceName(final Class> dtoClass) {
final var className = dtoClass.getSimpleName();
return className.substring(0, className.length() - DTO_LENGTH);
}
private void initJackson() {
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.registerModule(new JavaTimeModule());
}
@Override
public List<_Dto> all() {
return Lists.newArrayList(restTemplate.getForEntity(resourcesUri(), dtoArrClass).getBody());
}
public _Dto get(final _Id id) {
return get(singleResourceUri(id));
}
public _Dto add(final _Dto entity) {
return get(restTemplate.postForLocation(resourcesUri(), entity));
}
@Override
public List store(final Stream entities) {
final var list = entities.collect(Collectors.toList());
final var idsStr = joinToIds(list.stream());
final var url = singleResourceUri(idsStr);
restTemplate.put(url, entities);
return list;//todo:没有再get。
}
@Override
public void del(final Stream<_Dto> entities) {
final var ids = joinToIds(entities);
if (ids.isBlank()) {
return;
}
restTemplate.delete(singleResourceUri(ids));
}
private String joinToIds(final Stream extends _Dto> entities) {
return entities.map(e -> e.id().toString()).collect(Collectors.joining(","));
}
private _Dto get(final URI uri) {
if (uri == null) {
return null;
}
return restTemplate.getForObject(uri, dtoClass);
}
private URI singleResourceUri(final Object id) {
return singleResourceUriBuilder(id).toUri();
}
private UriComponents singleResourceUriBuilder(final Object id) {
return resourcesUriBuilder().pathSegment("{id}").buildAndExpand(id);
}
private String resourcesUri() {
return resourcesUriBuilder().toUriString();
}
private UriComponentsBuilder resourcesUriBuilder() {
return UriComponentsBuilder.newInstance().scheme(getProtocol()).host(getHost()).port(getPort())
.path(resourceName);
}
protected String getProtocol() {
return DEFAULT_PROTOCOL;
}
protected String getHost() {
return DEFAULT_HOST;
}
protected int getPort() {
return DEFAULT_PORT;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy