public class NacosConfigDatasourceTaskElementsOperation implements DatasourceTaskElementsOperation {
private static final Logger LOGGER = LoggerFactory.getLogger(NacosConfigDatasourceTaskElementsOperation.class);
/**
* Single-thread pool. Once the thread pool is blocked, we throw up the old task.
*/
private final ExecutorService pool = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(1), new NameThreadFactory("cron-nacos-datasource-update"),
new ThreadPoolExecutor.DiscardOldestPolicy());
private static final int DEFAULT_TIMEOUT = 3000;
private ConfigRefreshListener configListener;
private final String groupId;
private final String dataId;
private final Properties properties;
private final ConfigFormat configFormat;
/**
* Note: The Nacos config might be null if its initialization failed.
*/
private ConfigService configService;
/**
* Constructs an read-only DataSource with Nacos backend.
*
* @param serverAddr server address of Nacos, cannot be empty
* @param groupId group ID, cannot be empty
* @param dataId data ID, cannot be empty
* @param configFormat config format, cannot be null.
*/
public NacosConfigDatasourceTaskElementsOperation(final String serverAddr, final String groupId,
final String dataId, final ConfigFormat configFormat) {
this(buildProperties(serverAddr), groupId, dataId, configFormat);
}
/**
*
* @param properties properties for construct {@link ConfigService} using {@link NacosFactory#createConfigService(Properties)}
* @param groupId group ID, cannot be empty
* @param dataId data ID, cannot be empty
* @param configFormat config format, cannot be null.
*/
public NacosConfigDatasourceTaskElementsOperation(final Properties properties, final String groupId,
final String dataId, final ConfigFormat configFormat) {
if (StringUtils.isBlank(groupId) || StringUtils.isBlank(dataId)) {
throw new IllegalArgumentException(String.format("Bad argument: groupId=[%s], dataId=[%s]",
groupId, dataId));
}
Objects.requireNonNull(properties,
"Nacos properties must not be null, you could put some keys from PropertyKeyConst");
Objects.requireNonNull(configFormat, "Nacos configFormat must not be null");
this.groupId = groupId;
this.dataId = dataId;
this.properties = properties;
this.configFormat = configFormat;
initNacosListener();
}
private static Properties buildProperties(String serverAddr) {
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverAddr);
return properties;
}
private void initNacosListener() {
try {
this.configService = NacosFactory.createConfigService(this.properties);
}
catch (Exception ex) {
LOGGER.warn("[NacosConfigDatasourceTaskElementsOperation] Error occurred when initializing " +
"Nacos data source", ex);
}
}
@Override
public void purgeDatasourceTaskElements() {
List<NacosConfigTaskElement> elements = getElements();
for (NacosConfigTaskElement element : elements) {
element.purge();
}
publishConfig(elements);
}
@Override
public List<TaskElement> getDatasourceTaskElements() {
return Collections.unmodifiableList(getElements());
}
@Override
public void afterStart(List<TaskElement> fulledDatasourceTaskElement) {
updateConfig(fulledDatasourceTaskElement);
}
@Override
public List<TaskElement> getRuntimeNeedCheckDatasourceTaskElements() {
List<NacosConfigTaskElement> elements = getElements();
if (elements.isEmpty()) {
return Collections.emptyList();
}
elements = elements.stream()
.filter(t -> Objects.equals(t.getUpdateSign(), 1)
|| (Objects.equals(t.getUpdateSign(), 1) && t.getTaskId() == null))
.collect(Collectors.toList());
return Collections.unmodifiableList(elements);
}
@Override
public void afterRun(List<TaskElement> runtimeCheckedDatasourceTaskElement) {
updateConfig(runtimeCheckedDatasourceTaskElement);
}
@Nullable
@Override
public TaskElement getElementById(String id) {
List<NacosConfigTaskElement> elements = getElements();
return elements.isEmpty() ? null : elements.stream()
.filter(e-> Objects.equals(e.getTaskId(), id)).findFirst().orElse(null);
}
@Override
public boolean registerDefaultIfMainTaskInfoNotProvided() {
return false;
}
@Override
public void close() {
if (configService != null) {
if (configListener != null) {
configService.removeListener(dataId, groupId, configListener);
}
try {
configService.shutDown();
}
catch (Exception ex) {
LOGGER.warn("[NacosConfigDatasourceTaskElementsOperation] Error occurred when closing " +
"Nacos data source", ex);
}
}
pool.shutdownNow();
}
@Override
public void notifyMainTaskInfoNotProvidedAndNoDefaultUsed() {
configListener = new ConfigRefreshListener();
try {
// Add config listener.
configService.addListener(dataId, groupId, new ConfigRefreshListener());
}
catch (NacosException ex) {
LOGGER.warn("[NacosConfigDatasourceTaskElementsOperation] Error occurred when add " +
"config listener", ex);
throw new DataSourceDrivenException("Failed to add configuration and refresh listener", ex);
}
}
private List<NacosConfigTaskElement> getElements() {
if (configListener != null) {
return configListener.elements;
}
return getRemoteElements();
}
private List<NacosConfigTaskElement> getRemoteElements() {
String configInfo;
try {
configInfo = configService.getConfig(dataId, groupId, DEFAULT_TIMEOUT);
}
catch (NacosException ex) {
LOGGER.warn("[NacosConfigDatasourceTaskElementsOperation] Error occurred when get " +
"config info ", ex);
throw new DataSourceDrivenException("[NacosConfigDatasourceTaskElementsOperation] Error occurred when get " +
"config info ", ex);
}
return deserialize(configInfo);
}
private List<NacosConfigTaskElement> deserialize(String configInfo) {
try {
return NacosConfigTaskElementSerializerManager.deserialize(configFormat, configInfo);
}
catch (IOException ex) {
LOGGER.error("Failed to deserialize {} using {} format", configInfo, configFormat, ex);
throw new DataSourceDrivenException("Failed to deserialize " + configInfo +
" using " + configFormat + " format", ex);
}
}
private void updateConfig(List<TaskElement> elements) {
List<NacosConfigTaskElement> nacosConfigTaskElements = new ArrayList<>();
for (TaskElement taskElement : elements) {
if (taskElement instanceof NacosConfigTaskElement) {
nacosConfigTaskElements.add((NacosConfigTaskElement) taskElement);
}
}
if (nacosConfigTaskElements.isEmpty()) {
LOGGER.warn("There is no {} instance in the update item collection, so the configuration " +
"cannot be updated.", NacosConfigTaskElement.class.getName());
return;
}
publishConfig(nacosConfigTaskElements);
}
private void publishConfig(List<NacosConfigTaskElement> nacosConfigTaskElements) {
String newConfig = null;
try {
newConfig = NacosConfigTaskElementSerializerManager.serialize(configFormat, nacosConfigTaskElements);
configService.publishConfig(dataId, groupId, newConfig);
}
catch (IOException ex) {
LOGGER.error("Failed to serialize {} using {} format", nacosConfigTaskElements, configFormat, ex);
throw new DataSourceDrivenException("Failed to serialize " + nacosConfigTaskElements +
" using " + configFormat + " format", ex);
}
catch (NacosException ex) {
LOGGER.warn("[NacosConfigDatasourceTaskElementsOperation] Error occurred when " +
"publish config {}", newConfig, ex);
throw new DataSourceDrivenException("[NacosConfigDatasourceTaskElementsOperation] Error occurred when " +
"publish config " + newConfig, ex);
}
}
private class ConfigRefreshListener implements Listener {
volatile List<NacosConfigTaskElement> elements;
public ConfigRefreshListener() {
elements = getRemoteElements();
}
@Override
public Executor getExecutor() {
return pool;
}
@Override
public void receiveConfigInfo(String configInfo) {
LOGGER.info("[NacosDataSource] New property value received for (properties: {}) " +
"(dataId: {}, groupId: {}): {}", properties, dataId, groupId, configInfo);
elements = deserialize(configInfo);
}
}
} 根本你的理解 ,帮我为这个雷写上合理的 中英文java注释吧,先中文后英文