Commit 82a586a0 authored by ZWT's avatar ZWT

feat(吉林演示): 松原

1.修改风电站运行状态接口,增加模拟实际发电功率处理逻辑,完成接口冒烟测试;
2.修改天气数据处理定时任务,解决晚上十一点半天气预报数据处理异常问题,修改风资源预测数据和光伏资源预测数据时间处理逻辑,完成接口冒烟测试;
3.修改风机预测数据模块相关功能接口,增加判断当前部署环境逻辑,解决查询全量数据问题;
4.修改风机预测数据生成模块第三方风力发电数据生成功能,增加数据拆分逻辑,区分15分数据层级,完成功能冒烟测试;
5.修改风机预测监控页面历史风速统计接口,统计数据不显示问题及小数位过多问题;

BREAKING CHANGE: 无

Closes 无

[skip ci]
parent c1b0031e
/* JUG Java Uuid Generator
*
* Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fasterxml.uuid;
import java.io.IOException;
/**
* This is the API for utility classes optionally used by {@link UUIDTimer} to
* ensure that timestamp values used for generating time/location-based UUIDs
* are monotonically increasing, as well as that only one such generator
* is ever used on a single system, even in presence of multiple JVMs.
* <p>
* The default implementation used by JUG is
* {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}.
*/
public abstract class TimestampSynchronizer {
protected TimestampSynchronizer() {
}
/**
* Initialization method is will be called on an instance by
* {@link UUIDTimer} right after it's been configured with one.
* At this point the implementation instance should have been properly
* configured, and should be able to determine the first legal timestamp
* value (return value). Method should also initialize any locking that
* it does (if any), such as locking files it needs.
* <p>
* Return value thus indicates the lowest initial time value that can
* be used by the caller that can not have been used by previous
* incarnations of the UUID generator (assuming instance was able to
* find properly persisted data to figure that out).
* However, caller also needs to make sure that it will
* call {@link #update} when it actually needs the time stamp for the
* first time,
* since this method can not allocate timestamps beyond this initial
* value at this point.
*
* @return First (and last) legal timestamp to use; <code>0L</code> if it
* can not
* determine it and caller can use whatever value (current timestamp)
* it has access to.
*/
protected abstract long initialize()
throws IOException;
/**
* Method {@link UUIDTimer} will call if this synchronizer object is
* being replaced by another synchronizer (or removed, that is, no
* more synchronization is to be done). It will not be called if JVM
* terminates.
*/
protected abstract void deactivate()
throws IOException;
/**
* Method called by {@link UUIDTimer} to indicate that it has generated
* a timestamp value that is beyond last legal timestamp value.
* The method should only return once it has "locked" specified timestamp
* value (and possible additional ones).
*
* @param now Timestamp value caller wants to use, and that the
* synchronizer is asked to protect.
* @return First timestamp value that can NOT be used by the caller;
* has to be higher than the input timestamp value
*/
protected abstract long update(long now)
throws IOException;
}
\ No newline at end of file
/* JUG Java Uuid Generator
*
* Copyright (c) 2002 Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fasterxml.uuid;
/**
* UUIDClock is used by UUIDTimer to get the current time. The default
* implementation returns the time from the system clock, but this class can
* be overriden to return any number. This is useful when UUIDs with past or
* future timestamps should be generated, or when UUIDs must be generated in
* a reproducible manner.
*
* @since 3.3
*/
public class UUIDClock {
/**
* Returns the current time in milliseconds.
*/
public long currentTimeMillis() {
return System.currentTimeMillis();
}
}
\ No newline at end of file
package com.fasterxml.uuid;
/**
* Enumeration of different flavors of UUIDs: 5 specified by specs
* (<a href="http://tools.ietf.org/html/rfc4122">RFC-4122</a>)
* and one
* virtual entry ("UNKNOWN") to represent invalid one that consists of
* all zero bites
*/
public enum UUIDType {
TIME_BASED(1),
DCE(2),
NAME_BASED_MD5(3),
RANDOM_BASED(4),
NAME_BASED_SHA1(5),
TIME_BASED_REORDERED(6),
TIME_BASED_EPOCH(7),
FREE_FORM(8),
UNKNOWN(0);
private final int _raw;
UUIDType(int raw) {
_raw = raw;
}
/**
* Returns "raw" type constants, embedded within UUID bytes.
*/
public int raw() {
return _raw;
}
}
/* JUG Java Uuid Generator
*
* Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fasterxml.uuid.ext;
import com.fasterxml.uuid.TimestampSynchronizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* Implementation of {@link TimestampSynchronizer}, which uses file system
* as the storage and locking mechanism.
* <p>
* Synchronization is achieved by obtaining an exclusive file locks on two
* specified lock files, and by using the files to store first "safe" timestamp
* value that the generator can use; alternating between one to use to ensure
* one of them always contains a valid timestamp. Latter is needed to guard
* against system clock moving backwards after UUID generator restart.
* <p>
* Note: this class will only work on JDK 1.4 and above, since it requires
* NIO package to do proper file locking (as well as new opening mode for
* {@link RandomAccessFile}).
* <p>
* Also note that it is assumed that the caller has taken care to synchronize
* access to method to be single-threaded. As such, none of the methods
* is explicitly synchronized here.
*/
public final class FileBasedTimestampSynchronizer
extends TimestampSynchronizer {
protected final static String DEFAULT_LOCK_FILE_NAME1 = "uuid1.lck";
// // // Constants:
protected final static String DEFAULT_LOCK_FILE_NAME2 = "uuid2.lck";
/**
* The default update interval is 10 seconds, meaning that the
* synchronizer "reserves" next 10 seconds for generation. This
* also means that the lock files need to be accessed at most
* once every ten second.
*/
final static long DEFAULT_UPDATE_INTERVAL = 10L * 1000L;
private static final Logger logger = LoggerFactory.getLogger(FileBasedTimestampSynchronizer.class);
// // // Configuration:
protected final LockedFile mLocked1, mLocked2;
protected long mInterval = DEFAULT_UPDATE_INTERVAL;
// // // State:
/**
* Flag used to indicate which of timestamp files has the most
* recently succesfully updated timestamp value. True means that
* <code>mFile1</code> is more recent; false that <code>mFile2</code>
* is.
*/
boolean mFirstActive = false;
/**
* Constructor that uses default values for names of files to use
* (files will get created in the current working directory), as
* well as for the update frequency value (10 seconds).
*/
public FileBasedTimestampSynchronizer()
throws IOException {
this(new File(DEFAULT_LOCK_FILE_NAME1), new File(DEFAULT_LOCK_FILE_NAME2));
}
public FileBasedTimestampSynchronizer(File lockFile1, File lockFile2)
throws IOException {
this(lockFile1, lockFile2, DEFAULT_UPDATE_INTERVAL);
}
public FileBasedTimestampSynchronizer(File lockFile1, File lockFile2, long interval)
throws IOException {
mInterval = interval;
mLocked1 = new LockedFile(lockFile1);
boolean ok = false;
try {
mLocked2 = new LockedFile(lockFile2);
ok = true;
} finally {
if (!ok) {
mLocked1.deactivate();
}
}
// But let's leave reading up to initialization
}
/*
//////////////////////////////////////////////////////////////
// Configuration
//////////////////////////////////////////////////////////////
*/
protected static void doDeactivate(LockedFile lf1, LockedFile lf2) {
if (lf1 != null) {
lf1.deactivate();
}
if (lf2 != null) {
lf2.deactivate();
}
}
/*
//////////////////////////////////////////////////////////////
// Implementation of the API
//////////////////////////////////////////////////////////////
*/
public void setUpdateInterval(long interval) {
if (interval < 1L) {
throw new IllegalArgumentException("Illegal value (" + interval + "); has to be a positive integer value");
}
mInterval = interval;
}
/**
* This method is to be called only once by
* {@link com.fasterxml.uuid.UUIDTimer}. It
* should fetch the persisted timestamp value, which indicates
* first timestamp value that is guaranteed NOT to have used by
* a previous incarnation. If it can not determine such value, it
* is to return 0L as a marker.
*
* @return First timestamp value that was NOT locked by lock files;
* 0L to indicate that no information was read.
*/
@Override
protected long initialize() {
long ts1 = mLocked1.readStamp();
long ts2 = mLocked2.readStamp();
long result;
if (ts1 > ts2) {
mFirstActive = true;
result = ts1;
} else {
mFirstActive = false;
result = ts2;
}
/* Hmmh. If we didn't get a time stamp (-> 0), or if written time is
* ahead of current time, let's log something:
*/
if (result <= 0L) {
logger.warn("Could not determine safe timer starting point: assuming current system time is acceptable");
} else {
long now = System.currentTimeMillis();
//long diff = now - result;
/* It's more suspicious if old time was ahead... although with
* longer iteration values, it can be ahead without errors. So
* let's base check on current iteration value:
*/
if ((now + mInterval) < result) {
logger.warn("Safe timestamp read is {} milliseconds in future, and is greater than the inteval ({})", (result - now), mInterval);
}
/* Hmmh. Is there any way a suspiciously old timestamp could be
* harmful? It can obviously be useless but...
*/
}
return result;
}
@Override
public void deactivate() {
doDeactivate(mLocked1, mLocked2);
}
/*
//////////////////////////////////////////////////////////////
// Internal methods
//////////////////////////////////////////////////////////////
*/
/**
* @return Timestamp value that the caller can NOT use. That is, all
* timestamp values prior to (less than) this value can be used
* ok, but this value and ones after can only be used by first
* calling update.
*/
@Override
public long update(long now)
throws IOException {
long nextAllowed = now + mInterval;
/* We have to make sure to (over)write the one that is NOT
* actively used, to ensure that we always have fully persisted
* timestamp value, even if the write process gets interruped
* half-way through.
*/
if (mFirstActive) {
mLocked2.writeStamp(nextAllowed);
} else {
mLocked1.writeStamp(nextAllowed);
}
mFirstActive = !mFirstActive;
return nextAllowed;
}
}
/* JUG Java Uuid Generator
*
* Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fasterxml.uuid.ext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
/**
* Utility class used by {@link FileBasedTimestampSynchronizer} to do
* actual file access and locking.
* <p>
* Class stores simple timestamp values based on system time accessed
* using <code>System.currentTimeMillis()</code>. A single timestamp
* is stored into a file using {@link RandomAccessFile} in fully
* synchronized mode. Value is written in ISO-Latin (ISO-8859-1)
* encoding (superset of Ascii, 1 byte per char) as 16-digit hexadecimal
* number, surrounded by brackets. As such, file produced should
* always have exact size of 18 bytes. For extra robustness, slight
* variations in number of digits are accepeted, as are white space
* chars before and after bracketed value.
*/
class LockedFile {
/**
* Expected file length comes from hex-timestamp (16 digits),
* preamble "[0x",(3 chars) and trailer "]\r\n" (2 chars, linefeed
* to help debugging -- in some environments, missing trailing linefeed
* causes problems: also, 2-char linefeed to be compatible with all
* standard linefeeds on MacOS, Unix and Windows).
*/
final static int DEFAULT_LENGTH = 22;
final static long READ_ERROR = 0L;
final static String HEX_DIGITS = "0123456789abcdef";
// // // Configuration:
private static final Logger logger = LoggerFactory.getLogger(LockedFile.class);
// // // File state
final File mFile;
RandomAccessFile mRAFile;
FileChannel mChannel;
FileLock mLock;
ByteBuffer mWriteBuffer = null;
/**
* Flag set if the original file (created before this instance was
* created) had size other than default size and needs to be
* truncated
*/
boolean mWeirdSize;
/**
* Marker used to ensure that the timestamps stored are monotonously
* increasing. Shouldn't really be needed, since caller should take
* care of it, but let's be bit paranoid here.
*/
long mLastTimestamp = 0L;
LockedFile(File f)
throws IOException {
mFile = f;
RandomAccessFile raf = null;
FileChannel channel;
FileLock lock = null;
boolean ok = false;
try { // let's just use a single block to share cleanup code
raf = new RandomAccessFile(f, "rwd");
// Then lock them, if possible; if not, let's err out
channel = raf.getChannel();
if (channel == null) {
throw new IOException("Failed to access channel for '" + f + "'");
}
lock = channel.tryLock();
if (lock == null) {
throw new IOException("Failed to lock '" + f + "' (another JVM running UUIDGenerator?)");
}
ok = true;
} finally {
if (!ok) {
doDeactivate(f, raf, lock);
}
}
mRAFile = raf;
mChannel = channel;
mLock = lock;
}
protected static void doDeactivate(File f, RandomAccessFile raf,
FileLock lock) {
if (lock != null) {
try {
lock.release();
} catch (Throwable t) {
logger.error("Failed to release lock (for file '{}')", f, t);
}
}
if (raf != null) {
try {
raf.close();
} catch (Throwable t) {
logger.error("Failed to close file '{}'", f, t);
}
}
}
public void deactivate() {
RandomAccessFile raf = mRAFile;
mRAFile = null;
FileLock lock = mLock;
mLock = null;
doDeactivate(mFile, raf, lock);
}
public long readStamp() {
int size;
try {
size = (int) mChannel.size();
} catch (IOException ioe) {
logger.error("Failed to read file size", ioe);
return READ_ERROR;
}
mWeirdSize = (size != DEFAULT_LENGTH);
// Let's check specifically empty files though
if (size == 0) {
logger.warn("Missing or empty file, can not read timestamp value");
return READ_ERROR;
}
// Let's also allow some slack... but just a bit
if (size > 100) {
size = 100;
}
byte[] data = new byte[size];
try {
mRAFile.readFully(data);
} catch (IOException ie) {
logger.error("(file '{}') Failed to read {} bytes", mFile, size, ie);
return READ_ERROR;
}
/* Ok, got data. Now, we could just directly parse the bytes (since
* it is single-byte encoding)... but for convenience, let's create
* the String (this is only called once per JVM session)
*/
char[] cdata = new char[size];
for (int i = 0; i < size; ++i) {
cdata[i] = (char) (data[i] & 0xFF);
}
String dataStr = new String(cdata);
// And let's trim leading (and trailing, who cares)
dataStr = dataStr.trim();
long result = -1;
String err = null;
if (!dataStr.startsWith("[0")
|| dataStr.length() < 3
|| Character.toLowerCase(dataStr.charAt(2)) != 'x') {
err = "does not start with '[0x' prefix";
} else {
int ix = dataStr.indexOf(']', 3);
if (ix <= 0) {
err = "does not end with ']' marker";
} else {
String hex = dataStr.substring(3, ix);
if (hex.length() > 16) {
err = "length of the (hex) timestamp too long; expected 16, had " + hex.length() + " ('" + hex + "')";
} else {
try {
result = Long.parseLong(hex, 16);
} catch (NumberFormatException nex) {
err = "does not contain a valid hex timestamp; got '"
+ hex + "' (parse error: " + nex + ")";
}
}
}
}
// Unsuccesful?
if (result < 0L) {
logger.error("(file '{}') Malformed timestamp file contents: {}", mFile, err);
return READ_ERROR;
}
mLastTimestamp = result;
return result;
}
/*
//////////////////////////////////////////////////////////////
// Internal methods
//////////////////////////////////////////////////////////////
*/
public void writeStamp(long stamp)
throws IOException {
// Let's do sanity check first:
if (stamp <= mLastTimestamp) {
/* same stamp is not dangerous, but pointless... so warning,
* not an error:
*/
if (stamp == mLastTimestamp) {
logger.warn("(file '{}') Trying to re-write existing timestamp ({})", mFile, stamp);
return;
}
throw new IOException("" + mFile + " trying to overwrite existing value (" + mLastTimestamp + ") with an earlier timestamp (" + stamp + ")");
}
//System.err.println("!!!! Syncing ["+mFile+"] with "+stamp+" !!!");
// Need to initialize the buffer?
if (mWriteBuffer == null) {
mWriteBuffer = ByteBuffer.allocate(DEFAULT_LENGTH);
mWriteBuffer.put(0, (byte) '[');
mWriteBuffer.put(1, (byte) '0');
mWriteBuffer.put(2, (byte) 'x');
mWriteBuffer.put(19, (byte) ']');
mWriteBuffer.put(20, (byte) '\r');
mWriteBuffer.put(21, (byte) '\n');
}
// Converting to hex is simple
for (int i = 18; i >= 3; --i) {
int val = (((int) stamp) & 0x0F);
mWriteBuffer.put(i, (byte) HEX_DIGITS.charAt(val));
stamp = (stamp >> 4);
}
// and off we go:
mWriteBuffer.position(0); // to make sure we always write it all
mChannel.write(mWriteBuffer, 0L);
if (mWeirdSize) {
mRAFile.setLength(DEFAULT_LENGTH);
mWeirdSize = false;
}
// This is probably not needed (as the random access file is supposedly synced)... but let's be safe:
mChannel.force(false);
// And that's it!
}
}
package com.fasterxml.uuid.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoggerFacade {
private final Class<?> _forClass;
private WrappedLogger _logger;
private LoggerFacade(Class<?> forClass) {
_forClass = forClass;
}
public static LoggerFacade getLogger(Class<?> forClass) {
return new LoggerFacade(forClass);
}
public void warn(String msg) {
_warn(msg);
}
public void warn(String msg, Object arg) {
_warn(String.format(msg, arg));
}
public void warn(String msg, Object arg, Object arg2) {
_warn(String.format(msg, arg, arg2));
}
private synchronized void _warn(String message) {
if (_logger == null) {
_logger = WrappedLogger.logger(_forClass);
}
_logger.warn(message);
}
private static class WrappedLogger {
private final Logger _logger;
private WrappedLogger(Logger l) {
_logger = l;
}
public static WrappedLogger logger(Class<?> forClass) {
// Why all these contortions? To support case where Slf4j API missing
// (or, if it ever fails for not having impl) to just print to STDERR
try {
return new WrappedLogger(LoggerFactory.getLogger(forClass));
} catch (Throwable t) {
return new WrappedLogger(null);
}
}
public void warn(String message) {
if (_logger != null) {
_logger.warn(message);
} else {
System.err.println("WARN: " + message);
}
}
}
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment