Select Git revision
MetadataExtractionTest.java
MatMust.m 14.59 KiB
classdef MatMust < handle
%MATMUST A library to get deal with ESA webmust REST API
% Follow indication in methods help.
%
% +++++++++++++++++++++++++++++++++++++
% Creator: Carmelo Magnafico IAPS/INAF
% date: 20/06/2019
%
% +++++++++++++++++++++++++++++++++++++
properties
POSToptions
GEToptions
loginstatus
url
urlsub
userProjects
end
properties (SetAccess = private)
tockenfilename
tockenstruct
end
properties (Transient)
end
methods
function obj = MatMust(varargin)
% Initialize the values
obj.POSToptions = weboptions('RequestMethod', 'POST', 'ArrayFormat', 'json', 'Timeout',30, 'MediaType','application/json');
obj.GEToptions = weboptions('RequestMethod', 'GET', 'ArrayFormat', 'repeating', 'Timeout',30, 'MediaType','application/x-www-form-urlencoded');
obj.url = 'https://bepicolombo.esac.esa.int/webclient-must/';
obj.urlsub = 'mustlink/';
obj.tockenfilename = 'auth.json';
obj.loginstatus = false;
%check the url
if(nargin > 0)
if isfield(varargin{1},'url')
obj.url = varargin{1}.url;
end
end
%check url
[~,status] = urlread(obj.url);
if ~status
error('invalid URL')
end
if(MatMust_logincheck(obj))
disp('++++ MATMUST initialization ++++');
disp('++++ Access token valid. User logged in ++++');
disp('++++++++++++++++++++++++++++++++++++++++++++');
return
end
end
function e = MatMust_logincheck(obj)
f = fopen(obj.tockenfilename);
e = false;
% check if user is already logged in
if f > 0
raw = fread(f,inf);
tockenfilejson = jsondecode(char(raw));
if isfield(tockenfilejson,'token') & isfield(tockenfilejson,'expiresAt')
if length(split(tockenfilejson.token,'.')) == 3 & datetime(datenum(tockenfilejson.expiresAt, 'yyyy-mm-dd HH:MM:SS'), 'ConvertFrom','datenum', 'TimeZone','utc') > datetime(datetime(now, 'ConvertFrom','datenum', 'TimeZone','local'), 'TimeZone','utc')
obj.loginstatus = true;
obj.tockenstruct = tockenfilejson;
MatMust_getUserLinkedProjects(obj);
e=true;
else
disp('++++ MATMUST initialization ++++');
disp('++++ invalid or exiperd access token. User not logged in yet ++++');
disp('++++ User login needed - use MatMust_login to access ++++');
disp('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');
end
end
else
disp('++++ MATMUST initialization ++++');
disp('++++ cannot find access token. User not logged ++++');
disp('++++ User login needed - use MatMust_login to access ++++');
disp('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');
end
end
function t = MatMust_getTockenStatus(obj)
t = obj.loginresponse;
end
function t = MatMust_getUserProjects(obj)
if obj.loginstatus
query = 'usermanagement/projects';
obj.GEToptions.HeaderFields = {'Authorization', obj.tockenstruct.token};
try
response = webread([obj.url,obj.urlsub, query], obj.GEToptions);
t = response ;
catch ME
fprintf('+++ WARNING\n%s - %s\n', ME.identifier, ME.message)
end
end
end
function t = MatMust_getUserLinkedProjects(obj, varargin)
% Get the project to witch the logged in User belongs and have access to.
% if 'dump' option is set a screenslash is done
userInfo = MatMust_getUserInfo(obj);
obj.userProjects = userInfo.projects;
t = obj.userProjects;
if nargin > 1
if strcmp(varargin{1},'dump')
fprintf('+++++++++++++ PROJECTS LIST +++++++++++++\n');
for i = 1:numel(t)
fprintf('\tname: %s\n\tdescription: %s\n\tid: %i\n', t(i).name, t(i).description, t(i).id);
fprintf('+++++++++++++++++\n');
end
end
end
end
function t = MatMust_getUserInfo(obj)
if obj.loginstatus
query = 'usermanagement/userinfo';
obj.GEToptions.HeaderFields = {'Authorization', obj.tockenstruct.token};
try
response = webread([obj.url,obj.urlsub, query], obj.GEToptions);
t = response ;
catch ME
fprintf('+++ WARNING\n%s - %s\n', ME.identifier, ME.message)
end
end
end
function data = MatMust_getDataFromName(obj, ds, parname, dateStart, dateStop, varargin )
% data = MatMust_getDataFromName(obj, ds, parname, dateStart, dateStop, options )
% MatMust_getDataFromName get the data name parameter from the project name ds
% in the time interval dateStart, dateStop.
%
% inputs
% ------
% ds = 'string' -> name of the project i.e.'BEPICRUISE'
% parname = 'string' -> a parameter name i.e. 'NCAD7EB7'
% dateStart = 'yyyy-mm-dd HH:MM:SS' format date UTC time
% dateStop = 'yyyy-mm-dd HH:MM:SS' format date UTC time
% 'dump','plot' optional parameter to dump and plot the data
% intialize data output
data = [];
if ~(MatMust_logincheck(obj))
return
end
%validate ds
if isfield(obj.userProjects,'name')
if ~any(strcmp({obj.userProjects.name},ds))
disp('++++ Project not in Available User List, check ds name or check you access rigth ++++');
return
end
end
query = ['dataproviders/',ds,'/parameters/data'];
obj.GEToptions.HeaderFields = {'Authorization', obj.tockenstruct.token};
if isa(parname,'cell')
parname = char(join(parname,','));
end
args = {'key', 'name',...
'values', (parname),...
'from', (dateStart),...
'to', (dateStop),...
'calibrate', 'false',...
'mode', 'SIMPLE'};
try
data = webread([obj.url,obj.urlsub, query], args{:} ,obj.GEToptions);
catch ME
fprintf('+++ WARNING\n%s - %s\n', ME.identifier, ME.message)
return
end
%refine date string to adapt MATLAB date format
for i=1:numel(data)
data_par = data(i).data;
t = num2cell(datenum(datetime('1970-01-01', 'TimeZone','utc'))+(str2num(str2mat(data_par.date))/1000/86400));
[data(i).data.dateMAT] = deal(t{:});
clear t
end
if nargin > 5
if any(ismember(varargin,'dump'))
fprintf('+++++++++++++ DATA RESULT LIST +++++++++++++\n');
for i=1:numel(data)
data_par = data(i).data;
fprintf('%s-%s: %s -> %s\n', data(i).subsystem, data(i).type, data(i).name, data(i).description );
%TODO filter for several kind of dataType 'DOUBLE',
%'SIGNED_SMALL_INT', 'STRING'
switch data(i).dataType
case 'DOUBLE'
format = '%f';
case 'SIGNED_SMALL_INT'
format = '%i';
case 'STRING'
format = '%s';
end
format = ['%s - ',format,'\n'];
for i = 1:numel(data_par)
fprintf(format,datestr(data_par(i).dateMAT,'yyyy-mm-dd HH:MM:SS.FFF'), data_par(i).value );
end
fprintf('\n++++++++++++++\n\n');
end
fprintf('+++++++++++++++++++++++++++++++++++++++++\n');
end
if any(ismember(varargin,'plot'))
for i=1:numel(data)
data_par = data(i).data;
figure
title(sprintf('%s-%s: %s -> %s\n', data(i).subsystem, data(i).type, data(i).name, data(i).description ))
plot([data_par.dateMAT], [data_par.value], '-x' );
xlabel('time');
ylabel(data(i).unit);
datetick('x');
grid on
end
end
end
end
function t = MatMust_searchTMparFromName(obj, namequery, dataproviders, varargin)
if obj.loginstatus
query = 'metadata/treesearch';
obj.GEToptions.HeaderFields = {'Authorization', obj.tockenstruct.token};
if isa(dataproviders,'cell')
dataproviders = char(join(dataproviders,','));
end
try
response = webread([obj.url,obj.urlsub, query], 'field','name','text',namequery,'dataproviders', dataproviders ,obj.GEToptions);
t = response ;
catch ME
fprintf('+++ WARNING\n%s - %s\n', ME.identifier, ME.message)
end
if nargin > 3
if strcmp(varargin{1},'dump')
fprintf('+++++++++++++ PARAMETERS QUERY RESULT LIST +++++++++++++\n');
found = false;
for i = 1:numel(t)
if numel(t(i).children) > 0
found = true;
fprintf('\n\n\t+++++++++++++ %s LIST +++++++++++++\n', t(i).type);
for j = 1:numel(t(i).children)
par = t(i).children(j);
fprintf('\ttitle: %s\n\tname: %s\n\tdescription: %s\n\tid: %s\n', par.title, par.sortingField, par.label, par.id);
fprintf(' +++++++++++++++++\n');
end
end
end
if ~found, fprintf('++++ Nothing found ++++\n'); end
fprintf('++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n');
end
end
end
end
function [exit] = MatMust_login(obj, varargin )
% login
% https://bepicolombo.esac.esa.int/webclient-must/mustlink/api-docs/index.html#/Authentication/login
% input:
% "username": "string",
% "password": "string",
% "maxDuration": false
% output:
% "token": "string",
% "issuer": "string",
% "subject": "string",
% "issuedAt": "string",
% "expiresAt": "string",
% "expirationDate": "yyyy-mm-ddTHH:MM:SS.FFFZ"
if ~obj.loginstatus
% validation input
input_validation = struct('username', 'char', 'password', 'char', 'maxDuration', 'logical' );
exit = false;
if(nargin > 0)
inputs = varargin{1};
e = obj.MatMust_inputvalidator(inputs, input_validation);
if ~e
exit = false;
return
else
exit = true;
end
else
exit = false;
return
end
json_POST = inputs;
query = 'auth/login/';
obj.tockenstruct = webwrite([obj.url,obj.urlsub, query],json_POST,obj.POSToptions);
if isfield(obj.tockenstruct,'token')
disp('+++ Succesfully logged in +++')
obj.loginstatus = true;
else
disp('+++ Error in loggin +++')
obj.loginstatus = false;
end
%store into a file
if obj.loginstatus
f = fopen(obj.tockenfilename, 'w');
text = jsonencode(obj.tockenstruct);
fprintf(f,'%s',text);
fclose(f);
end
%store the UserAvailable Projects in class Property
MatMust_getUserLinkedProjects(obj);
else
exit = true;
disp('user already loggen in')
end
end
function exit = MatMust_inputvalidator(obj, input, validation)
% For now, every validation_input field is treated as required
% TODO: set add a subfield required at validataion json
exit = false;
val_fields = fields(validation);
for i = 1:numel(val_fields)
val_field = validation.(val_fields{i});
if isfield(input, val_fields{i})
if isa(input.(val_fields{i}), val_field)
exit = true;
else
exit = false;
end
else
exit = false;
end
end
end
end
end