Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
X-tee
X-Road-catalogue
Commits
f8fb4929
Commit
f8fb4929
authored
Dec 13, 2019
by
Vitali Stupin
Browse files
Adding support for REST services
parent
ce2301e3
Changes
12
Hide whitespace changes
Inline
Side-by-side
src/app/service.ts
0 → 100644
View file @
f8fb4929
export
class
Service
{
status
:
string
;
serviceCode
:
string
;
openapi
:
string
;
fullServiceName
:
string
;
}
src/app/subsystem-list/subsystem-item/subsystem-item.component.html
View file @
f8fb4929
<div
class=
"card"
>
<div
class=
"card-header pointerCursor"
(click)=
"showDetail()"
>
{{subsystem.fullSubsystemName}}
<span
class=
"badge badge-secondary"
*ngIf=
"!subsystem.methods.length && subsystem.subsystemStatus == 'OK'"
>
{{'subsystem.statusEmpty' | translate}}
</span>
<span
class=
"badge badge-secondary"
*ngIf=
"!subsystem.methods.length &&
!subsystem.services.length &&
subsystem.subsystemStatus == 'OK'"
>
{{'subsystem.statusEmpty' | translate}}
</span>
<span
class=
"badge badge-danger"
*ngIf=
"subsystem.subsystemStatus == 'ERROR'"
>
{{'subsystem.statusError' | translate}}
</span>
</div>
<div
class=
"card-body"
*ngIf=
"subsystem.subsystemStatus == 'ERROR'"
>
<p>
{{'subsystem.statusErrorInfo' | translate}}
</p>
</div>
<div
class=
"card-body"
*ngIf=
"subsystem.subsystemStatus == 'OK' && !subsystem.methods.length"
>
<div
class=
"card-body"
*ngIf=
"subsystem.subsystemStatus == 'OK' && !subsystem.methods.length
&& !subsystem.services.length
"
>
<p>
{{'subsystem.statusEmptyInfo' | translate}}
</p>
</div>
<div
class=
"card-body"
*ngIf=
"subsystem.subsystemStatus == 'OK' && subsystem.methods.length"
>
<div
class=
"card-body"
*ngIf=
"subsystem.subsystemStatus == 'OK' && (subsystem.methods.length || subsystem.services.length)"
>
<h6
*ngIf=
"subsystem.methods.length"
class=
"card-subtitle text-muted"
>
SOAP
</h6>
<p
*ngFor=
"let method of getMethodsPreview()"
>
{{method.fullMethodName}}
<a
href=
"{{getApiUrlBase()}}{{method.wsdl}}"
class=
"badge badge-success"
*ngIf=
"method.wsdl"
[target]=
"'_blank'"
>
WSDL
</a>
<span
class=
"badge badge-info"
*ngIf=
"method.methodStatus == 'REST'"
>
REST
</span>
<span
class=
"badge badge-danger"
*ngIf=
"method.methodStatus == 'ERROR'"
>
{{'subsystem.statusWsdlError' | translate}}
</span>
<span
class=
"badge badge-danger"
*ngIf=
"method.methodStatus == 'TIMEOUT'"
>
{{'subsystem.statusWsdlTimeout' | translate}}
</span>
<span
class=
"badge badge-warning"
*ngIf=
"method.methodStatus == 'SKIPPED'"
>
{{'subsystem.statusWsdlSkipped' | translate}}
</span>
</p>
<p
*ngIf=
"getNotInPreview() > 0"
class=
"pointerCursor"
(click)=
"showDetail()"
>
{{'subsystem.moreMethods' | translate:{"count": getNotInPreview()} }}
</p>
<p
*ngIf=
"getMethodsNotInPreview() > 0"
class=
"pointerCursor"
(click)=
"showDetail()"
>
{{'subsystem.moreMethods' | translate:{"count": getMethodsNotInPreview()} }}
</p>
<h6
*ngIf=
"subsystem.services.length"
class=
"card-subtitle text-muted"
>
REST
</h6>
<p
*ngFor=
"let service of getServicesPreview()"
>
{{service.fullServiceName}}
<a
href=
"{{getApiUrlBase()}}{{service.openapi}}"
class=
"badge badge-success"
*ngIf=
"service.openapi"
[target]=
"'_blank'"
>
OpenAPI
</a>
<span
class=
"badge badge-danger"
*ngIf=
"service.status == 'ERROR'"
>
{{'subsystem.statusOpenapiError' | translate}}
</span>
<span
class=
"badge badge-danger"
*ngIf=
"service.status == 'TIMEOUT'"
>
{{'subsystem.statusOpenapiTimeout' | translate}}
</span>
<span
class=
"badge badge-warning"
*ngIf=
"service.status == 'SKIPPED'"
>
{{'subsystem.statusOpenapiSkipped' | translate}}
</span>
</p>
<p
*ngIf=
"getServicesNotInPreview() > 0"
class=
"pointerCursor"
(click)=
"showDetail()"
>
{{'subsystem.moreMethods' | translate:{"count": getServicesNotInPreview()} }}
</p>
</div>
</div>
src/app/subsystem-list/subsystem-item/subsystem-item.component.spec.ts
View file @
f8fb4929
...
...
@@ -8,6 +8,7 @@ import { Router } from '@angular/router';
import
{
Method
}
from
'
src/app/method
'
;
import
{
AppConfigMock
}
from
'
src/app/app.config-mock
'
;
import
{
AppConfig
}
from
'
src/app/app.config
'
;
import
{
Service
}
from
'
src/app/service
'
;
const
PREVIEW_SIZE
=
5
;
...
...
@@ -48,8 +49,10 @@ describe('SubsystemItemComponent', () => {
memberCode
:
'
CODE
'
,
subsystemCode
:
'
SUB
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
OK
'
,
fullSubsystemName
:
'
INST/CLASS/CODE/SUB
'
,
methods
:
[]
methods
:
[],
services
:
[]
};
fixture
.
detectChanges
();
});
...
...
@@ -71,12 +74,28 @@ describe('SubsystemItemComponent', () => {
expect
(
component
.
getMethodsPreview
().
length
).
toBe
(
PREVIEW_SIZE
);
});
it
(
'
should preview services
'
,
()
=>
{
expect
(
component
.
getServicesPreview
().
length
).
toBe
(
0
);
for
(
let
i
=
0
;
i
<
PREVIEW_SIZE
+
10
;
i
++
)
{
component
.
subsystem
.
services
.
push
(
new
Service
());
}
expect
(
component
.
getServicesPreview
().
length
).
toBe
(
PREVIEW_SIZE
);
});
it
(
'
should calculate methods not in preview
'
,
()
=>
{
expect
(
component
.
getNotInPreview
()).
toBe
(
0
);
expect
(
component
.
get
Methods
NotInPreview
()).
toBe
(
0
);
for
(
let
i
=
0
;
i
<
PREVIEW_SIZE
+
10
;
i
++
)
{
component
.
subsystem
.
methods
.
push
(
new
Method
());
}
expect
(
component
.
getNotInPreview
()).
toBe
(
10
);
expect
(
component
.
getMethodsNotInPreview
()).
toBe
(
10
);
});
it
(
'
should calculate services not in preview
'
,
()
=>
{
expect
(
component
.
getServicesNotInPreview
()).
toBe
(
0
);
for
(
let
i
=
0
;
i
<
PREVIEW_SIZE
+
10
;
i
++
)
{
component
.
subsystem
.
services
.
push
(
new
Service
());
}
expect
(
component
.
getServicesNotInPreview
()).
toBe
(
10
);
});
it
(
'
should go to detail view
'
,
()
=>
{
...
...
src/app/subsystem-list/subsystem-item/subsystem-item.component.ts
View file @
f8fb4929
import
{
Component
,
OnInit
,
Input
}
from
'
@angular/core
'
;
import
{
Subsystem
}
from
'
../../subsystem
'
;
import
{
Method
}
from
'
../../method
'
;
import
{
Service
}
from
'
../../service
'
;
import
{
SubsystemsService
}
from
'
../../subsystems.service
'
;
import
{
Router
}
from
'
@angular/router
'
;
import
{
AppConfig
}
from
'
../../app.config
'
;
...
...
@@ -27,13 +28,24 @@ export class SubsystemItemComponent implements OnInit {
return
this
.
subsystem
.
methods
.
length
?
this
.
subsystem
.
methods
.
slice
(
0
,
this
.
config
.
getConfig
(
'
PREVIEW_SIZE
'
))
:
[];
}
getNotInPreview
():
number
{
getServicesPreview
():
Service
[]
{
return
this
.
subsystem
.
services
.
length
?
this
.
subsystem
.
services
.
slice
(
0
,
this
.
config
.
getConfig
(
'
PREVIEW_SIZE
'
))
:
[];
}
getMethodsNotInPreview
():
number
{
if
(
this
.
subsystem
.
methods
.
length
-
this
.
config
.
getConfig
(
'
PREVIEW_SIZE
'
)
<
0
)
{
return
0
;
}
return
this
.
subsystem
.
methods
.
length
-
this
.
config
.
getConfig
(
'
PREVIEW_SIZE
'
);
}
getServicesNotInPreview
():
number
{
if
(
this
.
subsystem
.
services
.
length
-
this
.
config
.
getConfig
(
'
PREVIEW_SIZE
'
)
<
0
)
{
return
0
;
}
return
this
.
subsystem
.
services
.
length
-
this
.
config
.
getConfig
(
'
PREVIEW_SIZE
'
);
}
showDetail
()
{
this
.
router
.
navigateByUrl
(
'
/
'
+
this
.
subsystem
.
xRoadInstance
...
...
src/app/subsystem.ts
View file @
f8fb4929
import
{
Method
}
from
'
./method
'
;
import
{
Service
}
from
'
./service
'
;
export
class
Subsystem
{
memberClass
:
string
;
subsystemCode
:
string
;
xRoadInstance
:
string
;
subsystemStatus
:
string
;
servicesStatus
:
string
;
memberCode
:
string
;
fullSubsystemName
:
string
;
methods
:
Method
[];
services
:
Service
[];
}
src/app/subsystem/subsystem.component.html
View file @
f8fb4929
...
...
@@ -11,30 +11,39 @@
<div
class=
"card"
>
<div
class=
"card-header"
>
{{subsystem.fullSubsystemName}}
<span
class=
"badge badge-secondary"
*ngIf=
"!subsystem.methods.length && subsystem.subsystemStatus == 'OK'"
>
{{'subsystem.statusEmpty' | translate}}
</span>
<span
class=
"badge badge-secondary"
*ngIf=
"!subsystem.methods.length &&
!subsystem.services.length &&
subsystem.subsystemStatus == 'OK'"
>
{{'subsystem.statusEmpty' | translate}}
</span>
<span
class=
"badge badge-danger"
*ngIf=
"subsystem.subsystemStatus == 'ERROR'"
>
{{'subsystem.statusError' | translate}}
</span>
</div>
<div
class=
"card-body"
*ngIf=
"subsystem.subsystemStatus == 'ERROR'"
>
<p>
{{'subsystem.statusErrorInfo' | translate}}
</p>
</div>
<div
class=
"card-body"
*ngIf=
"subsystem.subsystemStatus == 'OK' && !subsystem.methods.length"
>
<div
class=
"card-body"
*ngIf=
"subsystem.subsystemStatus == 'OK' && !subsystem.methods.length
&& !subsystem.services.length
"
>
<p>
{{'subsystem.statusEmptyInfo' | translate}}
</p>
</div>
<div
class=
"card-body"
*ngIf=
"subsystem.subsystemStatus == 'OK' && subsystem.methods.length"
>
<div
class=
"card-body"
*ngIf=
"subsystem.subsystemStatus == 'OK' && (subsystem.methods.length || subsystem.services.length)"
>
<h6
*ngIf=
"subsystem.methods.length"
class=
"card-subtitle text-muted"
>
SOAP
</h6>
<p
*ngFor=
"let method of subsystem.methods"
>
{{method.fullMethodName}}
<a
href=
"{{getApiUrlBase()}}{{method.wsdl}}"
class=
"badge badge-success"
*ngIf=
"method.wsdl"
[target]=
"'_blank'"
>
WSDL
</a>
<span
class=
"badge badge-info"
*ngIf=
"method.methodStatus == 'REST'"
>
REST
</span>
<span
class=
"badge badge-danger"
*ngIf=
"method.methodStatus == 'ERROR'"
>
{{'subsystem.statusWsdlError' | translate}}
</span>
<span
class=
"badge badge-danger"
*ngIf=
"method.methodStatus == 'TIMEOUT'"
>
{{'subsystem.statusWsdlTimeout' | translate}}
</span>
<span
class=
"badge badge-warning"
*ngIf=
"method.methodStatus == 'SKIPPED'"
>
{{'subsystem.statusWsdlSkipped' | translate}}
</span>
</p>
</p>
<h6
*ngIf=
"subsystem.services.length"
class=
"card-subtitle text-muted"
>
REST
</h6>
<p
*ngFor=
"let service of subsystem.services"
>
{{service.fullServiceName}}
<a
href=
"{{getApiUrlBase()}}{{service.openapi}}"
class=
"badge badge-success"
*ngIf=
"service.openapi"
[target]=
"'_blank'"
>
OpenAPI
</a>
<span
class=
"badge badge-danger"
*ngIf=
"service.status == 'ERROR'"
>
{{'subsystem.statusOpenapiError' | translate}}
</span>
<span
class=
"badge badge-danger"
*ngIf=
"service.status == 'TIMEOUT'"
>
{{'subsystem.statusOpenapiTimeout' | translate}}
</span>
<span
class=
"badge badge-warning"
*ngIf=
"service.status == 'SKIPPED'"
>
{{'subsystem.statusOpenapiSkipped' | translate}}
</span>
</p>
</div>
</div>
</div>
<br>
<p
*ngIf=
"subsystemSubject.value?.methods?.length"
>
<p
*ngIf=
"subsystemSubject.value?.methods?.length
|| subsystemSubject.value?.services?.length
"
>
<button
type=
"button"
[ngClass]=
"'btn btn-secondary'"
(click)=
"scrollToTop()"
>
{{'scrollToTop' | translate}}
</button>
</p>
src/app/subsystem/subsystem.component.spec.ts
View file @
f8fb4929
...
...
@@ -68,9 +68,11 @@ describe('SubsystemComponent', () => {
subsystemCode
:
''
,
xRoadInstance
:
''
,
subsystemStatus
:
''
,
servicesStatus
:
''
,
memberCode
:
''
,
fullSubsystemName
:
'
INST/CLASS/MEMBER/SYSTEM
'
,
methods
:
[]
methods
:
[],
services
:
[]
}
]);
});
...
...
@@ -114,9 +116,11 @@ describe('SubsystemComponent', () => {
subsystemCode
:
''
,
xRoadInstance
:
''
,
subsystemStatus
:
''
,
servicesStatus
:
''
,
memberCode
:
''
,
fullSubsystemName
:
'
INST/CLASS/MEMBER2/SYSTEM
'
,
methods
:
[]
methods
:
[],
services
:
[]
}
]);
fixture
=
TestBed
.
createComponent
(
SubsystemComponent
);
...
...
@@ -223,9 +227,11 @@ describe('SubsystemComponent (with instance version)', () => {
subsystemCode
:
''
,
xRoadInstance
:
''
,
subsystemStatus
:
''
,
servicesStatus
:
''
,
memberCode
:
''
,
fullSubsystemName
:
'
INST/CLASS/MEMBER/SYSTEM
'
,
methods
:
[]
methods
:
[],
services
:
[]
}
]);
});
...
...
src/app/subsystems.service.spec.ts
View file @
f8fb4929
...
...
@@ -2,6 +2,7 @@ import { SubsystemsService } from './subsystems.service';
import
{
of
,
defer
}
from
'
rxjs
'
;
import
{
Subsystem
}
from
'
./subsystem
'
;
import
{
Method
}
from
'
./method
'
;
import
{
Service
}
from
'
./service
'
;
import
{
HttpErrorResponse
}
from
'
@angular/common/http
'
;
import
{
tick
,
fakeAsync
}
from
'
@angular/core/testing
'
;
import
{
AppConfigMock
}
from
'
./app.config-mock
'
;
...
...
@@ -46,6 +47,22 @@ describe('SubsystemsService', () => {
subsystemStatus
:
'
OK
'
,
memberCode
:
'
MEMBER2
'
,
methods
:
[]
},
{
memberClass
:
'
CLASS
'
,
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
OK
'
,
memberCode
:
'
MEMBER3
'
,
methods
:
[],
services
:
[
{
status
:
'
OK
'
,
serviceCode
:
'
SERVICE
'
,
openapi
:
'
URL
'
}
]
}
];
const
expectedSubsystems
=
[
...
...
@@ -54,6 +71,7 @@ describe('SubsystemsService', () => {
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
ERROR
'
,
memberCode
:
'
MEMBER
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER/SYSTEM
'
,
methods
:
[
...
...
@@ -64,16 +82,37 @@ describe('SubsystemsService', () => {
serviceVersion
:
'
VER
'
,
fullMethodName
:
'
INST/CLASS/MEMBER/SYSTEM/SERVICE/VER
'
}
]
],
services
:
[]
},
{
memberClass
:
'
CLASS
'
,
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
ERROR
'
,
memberCode
:
'
MEMBER2
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER2/SYSTEM
'
,
methods
:
[]
methods
:
[],
services
:
[]
},
{
memberClass
:
'
CLASS
'
,
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
OK
'
,
memberCode
:
'
MEMBER3
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER3/SYSTEM
'
,
methods
:
[],
services
:
[
{
status
:
'
OK
'
,
serviceCode
:
'
SERVICE
'
,
openapi
:
'
URL
'
,
fullServiceName
:
'
INST/CLASS/MEMBER3/SYSTEM/SERVICE
'
}
]
}
];
httpClientSpy
.
get
.
and
.
returnValue
(
of
(
sourceSubsystems
));
...
...
@@ -184,19 +223,34 @@ describe('SubsystemsService', () => {
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
ERROR
'
,
memberCode
:
'
MEMBER
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER/SYSTEM
'
,
methods
:
[{}
as
Method
]
methods
:
[{}
as
Method
],
services
:
[]
},
{
memberClass
:
'
CLASS
'
,
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
ERROR
'
,
memberCode
:
'
MEMBER2
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER2/SYSTEM
'
,
methods
:
[]
}
methods
:
[],
services
:
[]
},
{
memberClass
:
'
CLASS
'
,
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
OK
'
,
memberCode
:
'
MEMBER3
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER3/SYSTEM
'
,
methods
:
[],
services
:
[{}
as
Service
]
},
];
const
expectedSubsystems
=
[
{
...
...
@@ -204,9 +258,22 @@ describe('SubsystemsService', () => {
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
ERROR
'
,
memberCode
:
'
MEMBER
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER/SYSTEM
'
,
methods
:
[{}
as
Method
]
methods
:
[{}
as
Method
],
services
:
[]
},
{
memberClass
:
'
CLASS
'
,
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
OK
'
,
memberCode
:
'
MEMBER3
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER3/SYSTEM
'
,
methods
:
[],
services
:
[{}
as
Service
]
}
];
service
.
subsystemsSubject
.
next
(
sourceSubsystems
);
...
...
@@ -221,6 +288,7 @@ describe('SubsystemsService', () => {
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
ERROR
'
,
memberCode
:
'
MEMBER
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER/SYSTEM
'
,
methods
:
[
...
...
@@ -238,16 +306,43 @@ describe('SubsystemsService', () => {
serviceVersion
:
'
VER
'
,
fullMethodName
:
'
INST/CLASS/MEMBER/SYSTEM/SERVICE2/VER
'
}
]
],
services
:
[]
},
{
memberClass
:
'
CLASS
'
,
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
ERROR
'
,
memberCode
:
'
MEMBER2
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER2/SYSTEM
'
,
methods
:
[]
methods
:
[],
services
:
[]
},
{
memberClass
:
'
CLASS
'
,
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
OK
'
,
memberCode
:
'
MEMBER3
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER3/SYSTEM
'
,
methods
:
[],
services
:
[
{
status
:
'
OK
'
,
serviceCode
:
'
SERVICE
'
,
openapi
:
'
URL
'
,
fullServiceName
:
'
INST/CLASS/MEMBER3/SYSTEM/RESTSRV
'
},
{
status
:
'
OK
'
,
serviceCode
:
'
SERVICE2
'
,
openapi
:
'
URL
'
,
fullServiceName
:
'
INST/CLASS/MEMBER3/SYSTEM/RESTSRV2
'
}
]
}
];
const
expectedSubsystems1
=
[
...
...
@@ -256,9 +351,11 @@ describe('SubsystemsService', () => {
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
ERROR
'
,
memberCode
:
'
MEMBER2
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER2/SYSTEM
'
,
methods
:
[]
methods
:
[],
services
:
[]
}
];
const
expectedSubsystems2
=
[
...
...
@@ -267,6 +364,7 @@ describe('SubsystemsService', () => {
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
ERROR
'
,
memberCode
:
'
MEMBER
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER/SYSTEM
'
,
methods
:
[
...
...
@@ -277,6 +375,27 @@ describe('SubsystemsService', () => {
serviceVersion
:
'
VER
'
,
fullMethodName
:
'
INST/CLASS/MEMBER/SYSTEM/SERVICE2/VER
'
}
],
services
:
[]
}
];
const
expectedSubsystems3
=
[
{
memberClass
:
'
CLASS
'
,
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
OK
'
,
memberCode
:
'
MEMBER3
'
,
fullSubsystemName
:
'
INST/CLASS/MEMBER3/SYSTEM
'
,
methods
:
[],
services
:
[
{
status
:
'
OK
'
,
serviceCode
:
'
SERVICE2
'
,
openapi
:
'
URL
'
,
fullServiceName
:
'
INST/CLASS/MEMBER3/SYSTEM/RESTSRV2
'
}
]
}
];
...
...
@@ -294,6 +413,12 @@ describe('SubsystemsService', () => {
tick
(
config
.
getConfig
(
'
FILTER_DEBOUNCE
'
));
expect
(
service
.
filteredSubsystemsSubject
.
value
).
toEqual
(
expectedSubsystems2
);
// Search member with multiple services
service
.
setFilter
(
'
RESTSRV2
'
);
// Waiting for a debounce time to apply filter
tick
(
config
.
getConfig
(
'
FILTER_DEBOUNCE
'
));
expect
(
service
.
filteredSubsystemsSubject
.
value
).
toEqual
(
expectedSubsystems3
);
// Search with limit
const
sourceSubsystems2
=
[];
for
(
let
i
=
0
;
i
<
config
.
getConfig
(
'
DEFAULT_LIMIT
'
)
+
1
;
i
++
)
{
...
...
@@ -303,9 +428,11 @@ describe('SubsystemsService', () => {
subsystemCode
:
'
SYSTEM
'
,
xRoadInstance
:
'
INST
'
,
subsystemStatus
:
'
OK
'
,
servicesStatus
:
'
OK
'
,
memberCode
:
'
MEMBER
'
+
i
,
fullSubsystemName
:
'
INST/CLASS/MEMBER
'
+
i
+
'
/SYSTEM
'
,
methods
:
[]
methods
:
[],
services
:
[]
}
);
}
...
...
src/app/subsystems.service.ts
View file @
f8fb4929
...
...
@@ -4,6 +4,7 @@ import { of, BehaviorSubject, Subject } from 'rxjs';
import
{
catchError
,
debounceTime
,
distinctUntilChanged
}
from
'
rxjs/operators
'
;
import
{
Subsystem
}
from
'
./subsystem
'
;
import
{
Method
}
from
'
./method
'
;
import
{
Service
}
from
'
./service
'
;
import
{
AppConfig
}
from
'
./app.config
'
;
import
{
InstanceVersion
}
from
'
./instance-version
'
;
...
...
@@ -41,35 +42,43 @@ export class SubsystemsService {
const
filtered
:
Subsystem
[]
=
[];
let
limit
:
number
=
this
.
limit
;
for
(
let
subsystem
of
this
.
subsystemsSubject
.
value
)
{
if
(
this
.
nonEmpty
&&
!
subsystem
.
methods
.
length
)
{
if
(
this
.
nonEmpty
&&
!
subsystem
.
methods
.
length
&&
!
subsystem
.
services
.
length
)
{
// Filtering out empty subsystems
continue
;
}
if
(
this
.
filter
!==
''
&&
!
subsystem
.
methods
.
length
&&
!
subsystem
.
services
.
length
)
{
// Subsystem without methods
// Subsystem without methods
and services
if
(
subsystem
.
fullSubsystemName
.
toLowerCase
().
indexOf
(
this
.
filter
.
toLowerCase
())
<
0
)
{
// Subsystem name does not match the filter
continue
;
}
}
else
if
(
this
.
filter
!==
''
)
{
// Subsystem with methods
// Subsystem with methods
and/or services
const
filteredMethods
:
Method
[]
=
[];
for
(
const
method
of
subsystem
.
methods
)
{
if
(
method
.
fullMethodName
.
toLowerCase
().
indexOf
(
this
.
filter
.
toLowerCase
())
>=
0
)
{
filteredMethods
.
push
(
method
);
}
}
if
(
!
filteredMethods
.
length
)
{
// No matching method names found
const
filteredServices
:
Service
[]
=
[];
for
(
const
service
of
subsystem
.
services
)
{
if
(
service
.
fullServiceName
.
toLowerCase
().
indexOf
(
this
.
filter
.
toLowerCase
())
>=
0
)
{
filteredServices
.
push
(
service
);
}
}
if
(
!
filteredMethods
.
length
&&
!
filteredServices
.
length
)
{
// No matching method and/or services names found
continue
;
}
// Copy object to avoid overwriting methods array in subsystem object
subsystem
=
Object
.
assign
(
Object
.
create
(
subsystem
),
subsystem
);
// Leaving only matcing methods
// Leaving only matcing methods
and services
subsystem
.
methods
=
filteredMethods
;
subsystem
.
services
=
filteredServices
;
}
filtered
.
push
(
subsystem
);
limit
-=
1
;
...
...
@@ -91,6 +100,18 @@ export class SubsystemsService {
+
'
/
'
+
method
.
serviceCode
+
'
/
'
+
method
.
serviceVersion
;
}
if
(
!
subsystem
.
servicesStatus
)
{
// Fix missing data in previous versions
subsystem
.
servicesStatus
=
'
ERROR
'
;
}
if
(
!
subsystem
.
services
)
{
// Fix missing data in previous versions
subsystem
.
services
=
[];
}
for
(
const
service
of
subsystem
.
services
)
{
service
.
fullServiceName
=
subsystem
.
fullSubsystemName
+
'
/
'
+
service
.
serviceCode
;
}
}
return
subsystems
;
}
...
...
src/assets/config.json
View file @
f8fb4929
...
...
@@ -8,8 +8,8 @@
},
"INSTANCES"
:
{
"EE"
:
"https://www.x-tee.ee/catalogue-data/EE/"
,
"ee-test"
:
"https://www.x-tee.ee/catalogue-data/
EE
/"
,
"ee-dev"
:
"https://www.x-tee.ee/catalogue-data/
EE
/"
"ee-test"
:
"https://www.x-tee.ee/catalogue-data/
ee-test
/"
,
"ee-dev"
:
"https://www.x-tee.ee/catalogue-data/
ee-dev
/"
},
"API_SERVICE"
:
"index.json"
,
"API_HISTORY"
:
"history.json"
,
...
...
src/assets/i18n/eng.json
View file @
f8fb4929
...
...
@@ -37,6 +37,9 @@
"statusWsdlError"
:
"Error while downloading or parsing of WSDL"
,
"statusWsdlTimeout"
:
"WSDL query timed out"
,
"statusWsdlSkipped"
:
"WSDL skipped due to previous timeout"
,
"statusOpenapiError"
:
"Error while downloading or parsing of OpenAPI"
,