17:37, EEST
March 16, 2017
10:46, EEST
April 3, 2012
Hi,
I’ll note first for future readers that in OPC UA 1.05 the Part 20 (https://reference.opcfoundation.org/Core/Part20/v105/docs/) “is just” the Annex C of Part 5 of 1.04 (https://reference.opcfoundation.org/Core/Part5/v104/docs/C).
There are 3 Types defined in the part FileType, FileDirectoryType and TemporaryFileTransferType (the FileSystem Object is FileDirectoryType instance). This is complicated topic. SDK supports FileType (though client-side usage is somewhat painful). It does allow you to make also FileDirectoryType and TemporaryFileTransferType instances, but doesn’t have implementations for the Methods, also the client-side nodes are limited to the API offered by OPC UA (Methods). I’ll separate FileType explanation to this first post and then make a second one for the rest.
In the server side, you must link com.prosysopc.ua.types.opcua.server.FileTypeNode instances with java.io.File instances using FileTypeNode.setFile(File), then the Methods of the instance work and related to the given file. I recommend adding and implementing IoManagerListener.onGetUserExecutable(ServiceContext, NodeId, UaMethod) on the NodeManagers having the instances to limit access to the Methods (If you trust all connecting clients then you can skip this, but e.g. any connected client could delete the contents of the file or write anything to it otherwise).
In the client side, this feature hasn’t been that much used, so com.prosysopc.ua.types.opcua.client.FileTypeImpl doesn’t contain much. We did some experiments in the past, the below code might be of some use (though note that I didn’t test it now, and the indentation due to forum is not that good), probably some day we will add this to the FileTypeImpl in some form:
throws ServiceException, StatusException, IOException {
long size = fileType.getSize().longValue();
DateTime timestamp = fileType.getTimestamp();
UnsignedInteger fileHandle = fileType.open(FileTypeOpenMode.Read);
FileOutputStream fos = new FileOutputStream(localFile, append);
try {
int actualBlockSize = getActualBlockSize();
for (long p = 0; p < size; p += actualBlockSize) {
fos.write(ByteString.asByteArray(fileType.read(fileHandle, actualBlockSize)));
}
} finally {
fos.close();
fileType.close(fileHandle);
}
localFile.setLastModified(timestamp.getTimeInMillis());
}
throws ServiceException, StatusException, IOException {
long size = localFile.length();
EnumSet<FileTypeOpenMode> mode = EnumSet.of(FileTypeOpenMode.Write);
if (append) {
mode.add(FileTypeOpenMode.Append);
} else {
mode.add(FileTypeOpenMode.EraseExisting);
}
UnsignedInteger fileHandle = fileType.open(mode);
FileInputStream fis = new FileInputStream(localFile);
try {
int actualBlockSize = getActualBlockSize();
byte[] buffer = new byte[actualBlockSize];
for (long p = 0; p < size; p += actualBlockSize) {
if (actualBlockSize > (size – p)) {
buffer = new byte[(int) (size – p)];
}
fis.read(buffer);
fileType.write(fileHandle, ByteString.valueOf(buffer));
}
} finally {
fis.close();
fileType.close(fileHandle);
}
}
(continues in next post)
11:26, EEST
April 3, 2012
(continuing post)
FileDirectoryType is not supported. Technically this means you can create instances of them, but all their methods would throw Bad_NotImplemented. However, there is an option for you to implement them manually via static methods (and would need to be repeated for each Method, and these should be called once, preferably before UaServer.start):
com.prosysopc.ua.types.opcua.server.FileDirectoryTypeNodeBase.setCreateDirectoryMethodImplementation(FileDirectoryTypeCreateDirectoryMethod)
(though since static methods are visible from the subtypes typically this would be called as FileDirectoryTypeNode.setCreateDirectoryMethodImplementation(..).
NOTE! It would be important to sanity-check the inputs. For example, assuming a base File, it would be important to prevent anyone adding e.g. “../” (in unix paths), doing that enough times to gain access to to the parent (and then potentially to the whole filesystem, this could lead to all sorts of attacks), or something else relevant or that the given parameters are really evaluated relative to the parent (and not e.g. unix root if the path starts with “/”). Same for deletion etc.
Same thing for TemporaryFileTransferType, however here is an additional issue (from the spec): ” The Methods GenerateFileForRead or GenerateFileForWrite generate a temporary FileType Object that is not browsable in the AddressSpace and can only be accessed with the NodeId and FileHandle returned by the Methods in the same Session.”.
SDK doesn’t support session-specific nodes, but technically this could be implementable via XXXListeners to forbid any other session from accessing the node. Probably the NodeIds would need to be Guids to prevent/minimize clashes of any other session nodes (since they all would be in the nodemanager and it would throw if duplicate NodeId).
SimulationServer doesn’t support any of these. Depending edition and version you might be able to get the instance to appear, but their Methods would throw the Bad_NotImplemented. Adding support for these in SimulationServer at least currently is not planned.
Most Users Ever Online: 1919
Currently Online:
46 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Heikki Tahvanainen: 402
hbrackel: 144
rocket science: 88
pramanj: 86
Francesco Zambon: 83
Ibrahim: 78
Sabari: 62
kapsl: 57
gjevremovic: 49
Xavier: 43
Member Stats:
Guest Posters: 0
Members: 726
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1529
Posts: 6471
Newest Members:
gabriellabachus, Deakin, KTP25Zof, Wojciech Kubala, efrennowell431, wilfredostuart, caitlynfajardo, jeromechubb7, franciscagrimwad, adult_galleryModerators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1032, Jimmy Ni: 26, Matti Siponen: 349, Lusetti: 0
Administrators: admin: 1