Commit a7cd143e authored by 's avatar
Browse files

first release of matlab class

parents
Loading
Loading
Loading
Loading

.gitignore

0 → 100644
+3 −0
Original line number Diff line number Diff line
# remove Auth file
matlab/test/auth.json
+347 −0
Original line number Diff line number Diff line
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
+0 −0

File added.

Preview size limit exceeded, changes collapsed.

+0 −0

File added.

Preview size limit exceeded, changes collapsed.

matlab/test/test.m

0 → 100644
+47 −0
Original line number Diff line number Diff line
% +++++++++++++++++++++++++++++++++++++++
%
% MATLAB webMust library for rest-API usage
% 
% test file 
% for any information regarding the API https://bepicolombo.esac.esa.int/webclient-must/mustlink/api-docs/index.html#/Projects/getProjects
%
% +++++++++++++++++++++++++++++++++++
% Creator: Carmelo Magnafico IAPS/INAF
% date: 10/07/2019
%
% ++++++++++++++++++

clear all
close all
addpath('./classes/');
M = MatMust;

% for info type help "MatMust_login"
MatMust_login(M, jsondecode('{"username": "ajejebrazorv",  "password": "123456%!", "maxDuration": false}'));


% Ask for the Projects available to the user
proj_list = M.MatMust_getUserLinkedProjects('dump');
%%%
% with output:
% +++++++++++++ PROJECTS LIST +++++++++++++
% name: BEPITEST
% 	description: Test Database for Instruments  Team
% 	id: 8
% +++++++++++++++++	
% [...]
% +++++++++++++++++
% 	name: BEPICRUISE
% 	description: BepiColombo Cruise Phase
% 	id: 9
% +++++++++++++++++

act_proj = 'BEPICRUISE';

% for info type "help MatMust_getDataFromName"
% MatMust_getDataFromName(obj, ds, parname, dateStart, dateStop, options  )
data = M.MatMust_getDataFromName('BEPICRUISE', 'NSA03016', '2018-11-26 13:00:00', '2018-11-26 13:40:00');

% or if you want to plot 
data = M.MatMust_getDataFromName('BEPICRUISE', 'NSA03016', '2018-11-26 13:00:00', '2018-11-26 13:40:00', 'plot');