You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
6.4 KiB
193 lines
6.4 KiB
package com.fr.design; |
|
|
|
import com.fr.concurrent.NamedThreadFactory; |
|
import com.fr.general.CloudCenter; |
|
import com.fr.general.CloudCenterConfig; |
|
import com.fr.general.http.HttpToolbox; |
|
import com.fr.log.FineLoggerFactory; |
|
import com.fr.stable.ProductConstants; |
|
import com.fr.stable.StableUtils; |
|
import com.fr.stable.StringUtils; |
|
import com.fr.stable.xml.XMLPrintWriter; |
|
import com.fr.stable.xml.XMLReaderHelper; |
|
import com.fr.stable.xml.XMLTools; |
|
import com.fr.stable.xml.XMLable; |
|
import com.fr.stable.xml.XMLableReader; |
|
import com.fr.third.javax.xml.stream.XMLStreamException; |
|
import com.fr.third.org.apache.commons.io.FileUtils; |
|
|
|
import java.io.ByteArrayOutputStream; |
|
import java.io.File; |
|
import java.io.FileInputStream; |
|
import java.io.FileNotFoundException; |
|
import java.io.IOException; |
|
import java.io.InputStream; |
|
import java.nio.charset.StandardCharsets; |
|
import java.util.HashMap; |
|
import java.util.Iterator; |
|
import java.util.Map; |
|
import java.util.concurrent.ExecutorService; |
|
import java.util.concurrent.Executors; |
|
|
|
/** |
|
* Created by kerry on 2021/10/22 |
|
*/ |
|
public class DesignerCloudURLManager implements XMLable { |
|
private static final String CLOUD_URL_INFO = "cloudUrl.info"; |
|
private static final String ROOT_XML_TAG = "CloudUrlInfoList"; |
|
private static final String CHILD_XML_TAG = "CloudUrlInfo"; |
|
private final Map<String, String> urlMap = new HashMap<>(); |
|
|
|
public static DesignerCloudURLManager getInstance() { |
|
return DesignerCloudURLManager.HOLDER.singleton; |
|
} |
|
|
|
private final ExecutorService executorService = Executors.newSingleThreadExecutor(new NamedThreadFactory("TestCloudConnectThread")); |
|
|
|
private volatile boolean testResult; |
|
|
|
|
|
private static class HOLDER { |
|
private static final DesignerCloudURLManager singleton = new DesignerCloudURLManager(); |
|
} |
|
|
|
private DesignerCloudURLManager() { |
|
loadURLXMLFile(); |
|
} |
|
|
|
public String acquireUrlByKind(String key) { |
|
String url = urlMap.getOrDefault(key, StringUtils.EMPTY); |
|
if (StringUtils.isEmpty(url)) { |
|
//本地缓存中为空时,直接从云中心获取,获取完成后异步更新本地缓存文件 |
|
String latestUrl = CloudCenter.getInstance().acquireConf(key, StringUtils.EMPTY); |
|
executorService.submit(() -> { |
|
updateURLXMLFile(key, latestUrl); |
|
}); |
|
return latestUrl; |
|
} |
|
//本地缓存不为空时,直接返回对应 url,同时异步更新 |
|
executorService.submit(() -> { |
|
String latestUrl = CloudCenter.getInstance().acquireConf(key, StringUtils.EMPTY); |
|
updateURLXMLFile(key, latestUrl); |
|
}); |
|
return url; |
|
} |
|
|
|
private synchronized void updateURLXMLFile(String key, String url) { |
|
if (StringUtils.isNotEmpty(url) && (!urlMap.containsKey(key) || !url.equals(urlMap.get(key)))) { |
|
urlMap.put(key, url); |
|
saveURLXMLFile(); |
|
} |
|
} |
|
|
|
|
|
public void testConnect() { |
|
executorService.submit(() -> { |
|
testResult = isOnline(); |
|
}); |
|
} |
|
|
|
public boolean isConnected() { |
|
return testResult; |
|
} |
|
|
|
public boolean isOnline() { |
|
if (CloudCenterConfig.getInstance().isOnline()) { |
|
String ping = acquireUrlByKind("ping"); |
|
if (StringUtils.isNotEmpty(ping)) { |
|
try { |
|
return StringUtils.isEmpty(HttpToolbox.get(ping)); |
|
} catch (Exception ignore) { |
|
} |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
|
|
/** |
|
* 加载本地 url 管理文件 |
|
*/ |
|
private void loadURLXMLFile() { |
|
if (!getInfoFile().exists()) { |
|
return; |
|
} |
|
XMLableReader reader = null; |
|
try (InputStream in = new FileInputStream(getInfoFile())) { |
|
// XMLableReader 还是应该考虑实现 Closable 接口的,这样就能使用 try-with 语句了 |
|
reader = XMLReaderHelper.createXMLableReader(in, XMLPrintWriter.XML_ENCODER); |
|
if (reader == null) { |
|
return; |
|
} |
|
reader.readXMLObject(this); |
|
} catch (FileNotFoundException e) { |
|
// do nothing |
|
} catch (XMLStreamException | IOException e) { |
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
|
} finally { |
|
try { |
|
if (reader != null) { |
|
reader.close(); |
|
} |
|
} catch (XMLStreamException e) { |
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
|
} |
|
} |
|
} |
|
|
|
private File getInfoFile() { |
|
|
|
File file = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), CLOUD_URL_INFO)); |
|
try { |
|
if (!file.exists()) { |
|
file.createNewFile(); |
|
} |
|
} catch (Exception ex) { |
|
FineLoggerFactory.getLogger().error(ex.getMessage(), ex); |
|
} |
|
return file; |
|
} |
|
|
|
/** |
|
* 保存到本地 URL 管理文件中,存放在 .Finereport110 中 |
|
*/ |
|
void saveURLXMLFile() { |
|
try { |
|
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
|
XMLTools.writeOutputStreamXML(this, out); |
|
out.flush(); |
|
out.close(); |
|
String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); |
|
FileUtils.writeStringToFile(getInfoFile(), fileContent, StandardCharsets.UTF_8); |
|
} catch (Exception ex) { |
|
FineLoggerFactory.getLogger().error(ex.getMessage()); |
|
} |
|
} |
|
|
|
|
|
@Override |
|
public void readXML(XMLableReader reader) { |
|
String tagName = reader.getTagName(); |
|
if (tagName.equals(CHILD_XML_TAG)) { |
|
String key = reader.getAttrAsString("key", StringUtils.EMPTY); |
|
String value = reader.getAttrAsString("url", StringUtils.EMPTY); |
|
this.urlMap.put(key, value); |
|
} |
|
} |
|
|
|
@Override |
|
public void writeXML(XMLPrintWriter xmlPrintWriter) { |
|
xmlPrintWriter.startTAG(ROOT_XML_TAG); |
|
Iterator<Map.Entry<String, String>> iterable = urlMap.entrySet().iterator(); |
|
while (iterable.hasNext()) { |
|
Map.Entry<String, String> entry = iterable.next(); |
|
xmlPrintWriter.startTAG(CHILD_XML_TAG).attr("key", entry.getKey()).attr("url", entry.getValue()).end(); |
|
} |
|
xmlPrintWriter.end(); |
|
} |
|
|
|
@Override |
|
public Object clone() throws CloneNotSupportedException { |
|
return null; |
|
} |
|
}
|
|
|