Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • simonrose/naming-backend
  • anderslindh1/naming-backend
  • andersharrisson/naming-backend
3 results
Show changes
Showing
with 1136 additions and 1229 deletions
File added
File added
To do - in particular at time of first set of releases
----------------------------------------------------------------------------------------------------
Content
(a) Before first release
1. verification - static
2. verification - data & application
(b) For first release
1. preparation - close & backup
2. migration scripts - run
3. verification - data & application
4. release - release & deploy
5. post - open & use
(c) For second release
1. preparation - close & backup
2. remove code - remove obsolete
3. migration script - make new, remove previous
4. upgrade database - to latest postgres
5. remove obsolete database content
6. flyway - introduce
7. release - release & deploy
8. post - open & use
----------------------------------------------------------------------------------------------------
Note
- First release
migration of database and functionality
( migration script V6.2 - audit tables contain all )
- Second release
one migration script only
upgrade Postgres database
introduction of Flyway
( possibility to do first and second release together and deploy Naming after second release )
------------------------------------------------------------------------------------------------
- Tests should be able to run at all times
see src/test/resources/INTEGRATIONTEST_DOCKER_RUN.md
To build and run all unit tests and integration tests (Docker) with code coverage.
- Verification of migration with endpoints
/verification - concerns verification of migration up to script V5 (pre audit)
- Configuration not mentioned below
additional configfuration may be required
- Keep migration documentation until judged ok to remove
keep docs/developer/naming_rest_api_migration.doc (.pdf) until some later time
to be able to guide users of old Naming REST API to new Naming REST API
- Respect integrations
----------------------------------------------------------------------------------------------------
(a) Before first release
1. verification - static
1.1 migration scripts
1.2 code
1.3 documentation
2. verification - data & application
2.1 use endpoints
/report
/report/about
/verification
/verification/migration_structures
/verification/migration_names
/verification/data_reachable
/verification/restapi_oldvsnew
2.2 analyse database
example sql queries
2.3 swagger
2.4 other
----------------------------------------------------------------------------------------------------
(b) For first release
1. preparation - close & backup
1.1 close Naming (old)
1.2 backup database
2. migration scripts - run
2.1 run migration script - src/main/resources/db/migration/V4__Schema_data_migration.sql
2.2 run migration script - src/main/resources/db/migration/V5.2__Data_transformation_status_deleted.sql
2.3 run migration script - src/main/resources/db/migration/V6.2__Schema_data_migration_audit.sql
2.7 run migration script - src/main/resources/db/migration/V7__Remove_user_notification_cc_list.sql
about
V4 - migrate to temporary tables, "work in progress"
V5.2 - delete entries that never have been active
V6.2 - migrate to permanent tables, audit tables with all entries
V7 - remove table as no longer used
3. verification - data & application
3.1 use old Naming REST API
3.2 use new Naming REST API
/report
/report/about
/verification
/verification/migration_structures
/verification/migration_names
/verification/data_reachable
/verification/restapi_oldvsnew
swagger
note
that if migration_structures fails, the difference in (# namepartrevision - # sum structures)
should match number of rows that were deleted in script V5.2
3.2 analyse database
example sql queries
3.3 other
4. release - release & deploy
5. post - open & use
4.1 open Naming (new)
----------------------------------------------------------------------------------------------------
(c) For second release
1. preparation - close & backup
1.1 close Naming (new)
1.2 backup database
2. remove code - remove obsolete
2.1. remove code - old and wip (work-in-progress)
src/main/java
org.openepics.names.old.business
org.openepics.names.old.model
org.openepics.names.old.nameviews
org.openepics.names.repository.model.wip
org.openepics.names.repository.old
org.openepics.names.repository.wip
org.openepics.names.rest.beans.old
org.openepics.names.rest.controller.old
org.openepics.names.util.old
org.openepics.names.util.wip
( org.openepics.names.old )
org.openepics.names.rest.controller/ReportController.java
org.openepics.names.rest.controller/VerificationController.java
src/test/java
org.openepics.names.repository.model.wip
org.openepics.names.docker.ReportIT.java
org.openepics.names.docker.VerificationIT.java
old - refers to code for old Naming tool - for reference and verification purposes
wip - refers to work-in-progress (temporary) code for new Naming tool - for migration and verification purposes
2.2. update documentation ( related to removal of code )
src/test/resources
INTEGRATIONTEST_DOCKER_RUN.md
docs/developer
naming_architecture_code.docx
naming_architecture_code.pdf
3. migration script - make new, remove previous
3.1 create with database management tool, e.g. DBeaver
3.2 give name V1__*.sql
3.3 update docker-compose-integrationtest.yml to use new migration script V1__*.sql instead of old migration scripts (V1 - V6)
4. upgrade database - to latest postgres
4.1 decide postgres version to upgrade to, e.g. 16.2
4.2 update docker compose files
docker-compose.yml
docker-compose-demo.yml
docker-compose-integrationtest.yml
5. remove obsolete database content
5.1 remove obsolete tables - tables no longer in use - see 6.2 - decide on flyway table
tables
remove
appinfo
device
devicerevision
( flyway_schema_history )
namepart
namepartrevision
useraccount
wip_devicegroup
wip_devicetype
wip_discipline
wip_name
wip_subsystem
wip_system
wip_systemgroup
keep
audit_name
audit_structure
devicegroup
devicetype
discipline
( flyway_schema_history )
name
subsystem
system
systemgroup
other
related to wip tables -- see also V4__Schema_data_migration.sql
indices
foreign keys
sequences
functions
6. flyway - introduce
6.1 possibly use existing table flyway_schema_history or create a new table
6.2 introduce flyway and make use of new migration script V1__*.sql - see 5.1 - decide on flyway table
6.3 update integration tests accordingly
docker-compose-integrationtest.yml
postgres:
volumes:
- ./src/main/resources/db/migration/V1__*.sql:/docker-entrypoint-initdb.d/V1__*.sql
7. release - release & deploy
8. post - open & use
8.1 open Naming (new)
----------------------------------------------------------------------------------------------------
README
----------
Folder contains content that is useful for naming-backend.
Content
- useful.odg LibreOffice Draw document, content may be exported or copied to image edit tool
and then exported to images that can be put in naming-backend
File added
-- --------------------------------------------------------------------------------
-- About
-- migration script
-- postgresql 9.6.7
-- Content
-- structures
-- name
-- data structures level 1
-- data structures level 2
-- data structures level 3
-- data name level 1
-- data name level 2
-- data name level 3
-- index
-- latest
-- foreign key
-- index
-- sequence
-- primary key
-- function
-- Note
-- order of items is important
-- --------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------
-- structures
-- --------------------------------------------------------------------------------
CREATE TABLE systemgroup (
id bigint NOT NULL,
version integer,
uuid character varying(255),
name character varying(255),
mnemonic character varying(255),
mnemonic_equivalence character varying(255),
description character varying(255),
status character varying(255),
latest boolean NOT NULL,
deleted boolean NOT NULL,
requested timestamp without time zone,
requested_by character varying(255),
requested_comment character varying(255),
processed timestamp without time zone,
processed_by character varying(255),
processed_comment character varying(255)
);
CREATE TABLE system (
id bigint NOT NULL,
version integer,
uuid character varying(255),
parent_uuid character varying(255),
name character varying(255),
mnemonic character varying(255),
mnemonic_equivalence character varying(255),
description character varying(255),
status character varying(255),
latest boolean NOT NULL,
deleted boolean NOT NULL,
requested timestamp without time zone,
requested_by character varying(255),
requested_comment character varying(255),
processed timestamp without time zone,
processed_by character varying(255),
processed_comment character varying(255)
);
CREATE TABLE subsystem (
id bigint NOT NULL,
version integer,
uuid character varying(255),
parent_uuid character varying(255),
name character varying(255),
mnemonic character varying(255),
mnemonic_equivalence character varying(255),
description character varying(255),
status character varying(255),
latest boolean NOT NULL,
deleted boolean NOT NULL,
requested timestamp without time zone,
requested_by character varying(255),
requested_comment character varying(255),
processed timestamp without time zone,
processed_by character varying(255),
processed_comment character varying(255)
);
-- --------------------------------------------------------------------------------
CREATE TABLE discipline (
id bigint NOT NULL,
version integer,
uuid character varying(255),
name character varying(255),
mnemonic character varying(255),
mnemonic_equivalence character varying(255),
description character varying(255),
status character varying(255),
latest boolean NOT NULL,
deleted boolean NOT NULL,
requested timestamp without time zone,
requested_by character varying(255),
requested_comment character varying(255),
processed timestamp without time zone,
processed_by character varying(255),
processed_comment character varying(255)
);
CREATE TABLE devicegroup (
id bigint NOT NULL,
version integer,
uuid character varying(255),
parent_uuid character varying(255),
name character varying(255),
mnemonic character varying(255),
mnemonic_equivalence character varying(255),
description character varying(255),
status character varying(255),
latest boolean NOT NULL,
deleted boolean NOT NULL,
requested timestamp without time zone,
requested_by character varying(255),
requested_comment character varying(255),
processed timestamp without time zone,
processed_by character varying(255),
processed_comment character varying(255)
);
CREATE TABLE devicetype (
id bigint NOT NULL,
version integer,
uuid character varying(255),
parent_uuid character varying(255),
name character varying(255),
mnemonic character varying(255),
mnemonic_equivalence character varying(255),
description character varying(255),
status character varying(255),
latest boolean NOT NULL,
deleted boolean NOT NULL,
requested timestamp without time zone,
requested_by character varying(255),
requested_comment character varying(255),
processed timestamp without time zone,
processed_by character varying(255),
processed_comment character varying(255)
);
-- --------------------------------------------------------------------------------
-- name
-- --------------------------------------------------------------------------------
CREATE TABLE name (
id bigint NOT NULL,
version integer,
uuid character varying(255),
systemgroup_uuid character varying(255),
system_uuid character varying(255),
subsystem_uuid character varying(255),
devicetype_uuid character varying(255),
instance_index character varying(255),
convention_name character varying(255),
convention_name_equivalence character varying(255),
description character varying(255),
status character varying(255),
latest boolean NOT NULL,
deleted boolean NOT NULL,
requested timestamp without time zone,
requested_by character varying(255),
requested_comment character varying(255),
processed timestamp without time zone,
processed_by character varying(255),
processed_comment character varying(255)
);
-- --------------------------------------------------------------------------------
-- data structures level 1
-- --------------------------------------------------------------------------------
insert into systemgroup (
id,
version,
uuid,
name,
mnemonic,
mnemonic_equivalence,
description,
status,
latest,
deleted,
requested,
requested_by,
requested_comment,
processed,
processed_by,
processed_comment
)
select npr1.id, npr1."version", np1.uuid, npr1."name", npr1.mnemonic, npr1.mnemoniceqclass, npr1.description, npr1.status, false, npr1.deleted,
npr1.requestdate, ua_r.username as requestedBy, npr1.requestercomment, npr1.processdate, ua_p.username as processedBy, npr1.processorcomment
from namepartrevision npr1
inner join namepart np1 on npr1.namepart_id = np1.id
left join useraccount ua_r on npr1.requestedby_id = ua_r.id
left join useraccount ua_p on npr1.processedby_id = ua_p.id
where np1.nameparttype = 'SECTION' and npr1.parent_id is null;
insert into discipline (
id,
version,
uuid,
name,
mnemonic,
mnemonic_equivalence,
description,
status,
latest,
deleted,
requested,
requested_by,
requested_comment,
processed,
processed_by,
processed_comment
)
select npr1.id, npr1."version", np1.uuid, npr1."name", npr1.mnemonic, npr1.mnemoniceqclass, npr1.description, npr1.status, false, npr1.deleted,
npr1.requestdate, ua_r.username as requestedBy, npr1.requestercomment, npr1.processdate, ua_p.username as processedBy, npr1.processorcomment
from namepartrevision npr1
inner join namepart np1 on npr1.namepart_id = np1.id
left join useraccount ua_r on npr1.requestedby_id = ua_r.id
left join useraccount ua_p on npr1.processedby_id = ua_p.id
where np1.nameparttype = 'DEVICE_TYPE' and npr1.parent_id is null;
-- --------------------------------------------------------------------------------
-- data structures level 2
-- --------------------------------------------------------------------------------
insert into system (
id,
version,
uuid,
parent_uuid,
name,
mnemonic,
mnemonic_equivalence,
description,
status,
latest,
deleted,
requested,
requested_by,
requested_comment,
processed,
processed_by,
processed_comment
)
select npr2.id, npr2."version", np2.uuid, np22.uuid,
npr2."name", npr2.mnemonic, npr2.mnemoniceqclass, npr2.description,
npr2.status, false, npr2.deleted, npr2.requestdate, ua_r.username as requestedBy, npr2.requestercomment, npr2.processdate, ua_p.username as processedBy, npr2.processorcomment
from namepartrevision npr2
inner join namepart np2 on npr2.namepart_id = np2.id
inner join namepart np22 on npr2.parent_id = np22.id
left join useraccount ua_r on npr2.requestedby_id = ua_r.id
left join useraccount ua_p on npr2.processedby_id = ua_p.id
where np2.nameparttype = 'SECTION' and npr2.parent_id in
(select npr1.namepart_id from namepartrevision npr1, namepart np1 where npr1.namepart_id = np1.id and np1.nameparttype = 'SECTION' and npr1.parent_id is null);
insert into devicegroup (
id,
version,
uuid,
parent_uuid,
name,
mnemonic,
mnemonic_equivalence,
description,
status,
latest,
deleted,
requested,
requested_by,
requested_comment,
processed,
processed_by,
processed_comment
)
select npr2.id, npr2."version", np2.uuid, np22.uuid,
npr2."name", npr2.mnemonic, npr2.mnemoniceqclass, npr2.description,
npr2.status, false, npr2.deleted, npr2.requestdate, ua_r.username as requestedBy, npr2.requestercomment, npr2.processdate, ua_p.username as processedBy, npr2.processorcomment
from namepartrevision npr2
inner join namepart np2 on npr2.namepart_id = np2.id
inner join namepart np22 on npr2.parent_id = np22.id
left join useraccount ua_r on npr2.requestedby_id = ua_r.id
left join useraccount ua_p on npr2.processedby_id = ua_p.id
where np2.nameparttype = 'DEVICE_TYPE' and npr2.parent_id in
(select npr1.namepart_id from namepartrevision npr1, namepart np1 where npr1.namepart_id = np1.id and np1.nameparttype = 'DEVICE_TYPE' and npr1.parent_id is null);
-- --------------------------------------------------------------------------------
-- data structures level 3
-- --------------------------------------------------------------------------------
insert into subsystem (
id,
version,
uuid,
parent_uuid,
name,
mnemonic,
mnemonic_equivalence,
description,
status,
latest,
deleted,
requested,
requested_by,
requested_comment,
processed,
processed_by,
processed_comment
)
select npr3.id, npr3."version", np3.uuid, np32.uuid,
npr3."name", npr3.mnemonic, npr3.mnemoniceqclass, npr3.description,
npr3.status, false, npr3.deleted, npr3.requestdate, ua_r.username as requestedBy, npr3.requestercomment, npr3.processdate, ua_p.username as processedBy, npr3.processorcomment
from namepartrevision npr3
inner join namepart np3 on npr3.namepart_id = np3.id
inner join namepart np32 on npr3.parent_id = np32.id
left join useraccount ua_r on npr3.requestedby_id = ua_r.id
left join useraccount ua_p on npr3.processedby_id = ua_p.id
where np3.nameparttype = 'SECTION' and npr3.parent_id in
(
select npr2.namepart_id from namepartrevision npr2, namepart np2 where npr2.namepart_id = np2.id and np2.nameparttype = 'SECTION' and npr2.parent_id in
(select npr1.namepart_id from namepartrevision npr1, namepart np1 where npr1.namepart_id = np1.id and np1.nameparttype = 'SECTION' and npr1.parent_id is null)
);
insert into devicetype (
id,
version,
uuid,
parent_uuid,
name,
mnemonic,
mnemonic_equivalence,
description,
status,
latest,
deleted,
requested,
requested_by,
requested_comment,
processed,
processed_by,
processed_comment
)
select npr3.id, npr3."version", np3.uuid, np32.uuid,
npr3."name", npr3.mnemonic, npr3.mnemoniceqclass, npr3.description,
npr3.status, false, npr3.deleted, npr3.requestdate, ua_r.username as requestedBy, npr3.requestercomment, npr3.processdate, ua_p.username as processedBy, npr3.processorcomment
from namepartrevision npr3
inner join namepart np3 on npr3.namepart_id = np3.id
inner join namepart np32 on npr3.parent_id = np32.id
left join useraccount ua_r on npr3.requestedby_id = ua_r.id
left join useraccount ua_p on npr3.processedby_id = ua_p.id
where np3.nameparttype = 'DEVICE_TYPE' and npr3.parent_id in
(
select npr2.namepart_id from namepartrevision npr2, namepart np2 where npr2.namepart_id = np2.id and np2.nameparttype = 'DEVICE_TYPE' and npr2.parent_id in
(select npr1.namepart_id from namepartrevision npr1, namepart np1 where npr1.namepart_id = np1.id and np1.nameparttype = 'DEVICE_TYPE' and npr1.parent_id is null)
);
-- --------------------------------------------------------------------------------
-- data name level 1
-- --------------------------------------------------------------------------------
insert into name (
id,
version,
uuid,
systemgroup_uuid,
system_uuid,
subsystem_uuid,
devicetype_uuid,
instance_index,
convention_name,
convention_name_equivalence,
description,
status,
latest,
deleted,
requested,
requested_by,
requested_comment,
processed,
processed_by,
processed_comment
)
select dr.id, dr.version, d.uuid,
np_s.uuid,
null,
null,
np_d.uuid,
dr.instanceindex, dr.conventionname, dr.conventionnameeqclass, dr.additionalinfo, null, false, dr.deleted,
dr.requestdate, ua_r.username as requestedBy, null, null, null, dr.processorComment
from devicerevision dr
inner join device d on dr.device_id = d.id
inner join namepart np_s on dr.section_id = np_s.id
left outer join namepart np_d on dr.devicetype_id = np_d.id
left join useraccount ua_r on dr.requestedby_id = ua_r.id
where dr.section_id in
(
select np.id from namepart np, namepartrevision npr where np.id = npr.namepart_id and npr.parent_id is null
);
-- --------------------------------------------------------------------------------
-- data name level 2
-- --------------------------------------------------------------------------------
insert into name (
id,
version,
uuid,
systemgroup_uuid,
system_uuid,
subsystem_uuid,
devicetype_uuid,
instance_index,
convention_name,
convention_name_equivalence,
description,
status,
latest,
deleted,
requested,
requested_by,
requested_comment,
processed,
processed_by,
processed_comment
)
select dr.id, dr.version, d.uuid,
null,
np_s.uuid,
null,
np_d.uuid,
dr.instanceindex, dr.conventionname, dr.conventionnameeqclass, dr.additionalinfo, null, false, dr.deleted,
dr.requestdate, ua_r.username as requestedBy, null, null, null, dr.processorComment
from devicerevision dr
inner join device d on dr.device_id = d.id
inner join namepart np_s on dr.section_id = np_s.id
left outer join namepart np_d on dr.devicetype_id = np_d.id
left join useraccount ua_r on dr.requestedby_id = ua_r.id
where dr.section_id in
(
select np.id from namepart np, namepartrevision npr where np.id = npr.namepart_id and npr.parent_id in
(
select np2.id from namepart np2, namepartrevision npr2 where np2.id = npr2.namepart_id and npr2.parent_id is null
)
);
-- --------------------------------------------------------------------------------
-- data name level 3
-- --------------------------------------------------------------------------------
insert into name (
id,
version,
uuid,
systemgroup_uuid,
system_uuid,
subsystem_uuid,
devicetype_uuid,
instance_index,
convention_name,
convention_name_equivalence,
description,
status,
latest,
deleted,
requested,
requested_by,
requested_comment,
processed,
processed_by,
processed_comment
)
select dr.id, dr.version, d.uuid,
null,
null,
np_s.uuid,
np_d.uuid,
dr.instanceindex, dr.conventionname, dr.conventionnameeqclass, dr.additionalinfo, null, false, dr.deleted,
dr.requestdate, ua_r.username as requestedBy, null, null, null, dr.processorComment
from devicerevision dr
inner join device d on dr.device_id = d.id
inner join namepart np_s on dr.section_id = np_s.id
left outer join namepart np_d on dr.devicetype_id = np_d.id
left join useraccount ua_r on dr.requestedby_id = ua_r.id
where dr.section_id in
(
select np.id from namepart np, namepartrevision npr where np.id = npr.namepart_id and npr.parent_id in
(
select np2.id from namepart np2, namepartrevision npr2 where np2.id = npr2.namepart_id and npr2.parent_id in
(
select np3.id from namepart np3, namepartrevision npr3 where np3.id = npr3.namepart_id and npr3.parent_id is null
)
)
);
-- --------------------------------------------------------------------------------
-- index
-- --------------------------------------------------------------------------------
CREATE INDEX systemgroup_id_idx ON public.systemgroup (id);
CREATE INDEX systemgroup_uuid_idx ON public.systemgroup (uuid);
CREATE INDEX systemgroup_mnemonic_idx ON public.systemgroup (mnemonic);
CREATE INDEX systemgroup_status_idx ON public.systemgroup (status);
CREATE INDEX systemgroup_deleted_idx ON public.systemgroup (deleted);
CREATE INDEX system_id_idx ON public.system (id);
CREATE INDEX system_uuid_idx ON public.system (uuid);
CREATE INDEX system_parent_uuid_idx ON public.system (parent_uuid);
CREATE INDEX system_mnemonic_idx ON public.system (mnemonic);
CREATE INDEX system_status_idx ON public.system (status);
CREATE INDEX system_deleted_idx ON public.system (deleted);
CREATE INDEX subsystem_id_idx ON public.subsystem (id);
CREATE INDEX subsystem_uuid_idx ON public.subsystem (uuid);
CREATE INDEX subsystem_parent_uuid_idx ON public.subsystem (parent_uuid);
CREATE INDEX subsystem_mnemonic_idx ON public.subsystem (mnemonic);
CREATE INDEX subsystem_status_idx ON public.subsystem (status);
CREATE INDEX subsystem_deleted_idx ON public.subsystem (deleted);
CREATE INDEX discipline_id_idx ON public.discipline (id);
CREATE INDEX discipline_uuid_idx ON public.discipline (uuid);
CREATE INDEX discipline_mnemonic_idx ON public.discipline (mnemonic);
CREATE INDEX discipline_status_idx ON public.discipline (status);
CREATE INDEX discipline_deleted_idx ON public.discipline (deleted);
CREATE INDEX devicegroup_id_idx ON public.devicegroup (id);
CREATE INDEX devicegroup_uuid_idx ON public.devicegroup (uuid);
CREATE INDEX devicegroup_parent_uuid_idx ON public.devicegroup (parent_uuid);
CREATE INDEX devicegroup_mnemonic_idx ON public.devicegroup (mnemonic);
CREATE INDEX devicegroup_status_idx ON public.devicegroup (status);
CREATE INDEX devicegroup_deleted_idx ON public.devicegroup (deleted);
CREATE INDEX devicetype_id_idx ON public.devicetype (id);
CREATE INDEX devicetype_uuid_idx ON public.devicetype (uuid);
CREATE INDEX devicetype_parent_uuid_idx ON public.devicetype (parent_uuid);
CREATE INDEX devicetype_mnemonic_idx ON public.devicetype (mnemonic);
CREATE INDEX devicetype_status_idx ON public.devicetype (status);
CREATE INDEX devicetype_deleted_idx ON public.devicetype (deleted);
CREATE INDEX name_uuid_idx ON public.name (uuid);
-- --------------------------------------------------------------------------------
-- latest
-- --------------------------------------------------------------------------------
update systemgroup sg set latest = true where sg.id = (
select max(sg2.id) from systemgroup sg2 where sg2.uuid = sg.uuid and sg2.status = 'APPROVED'
);
update system sys set latest = true where sys.id = (
select max(sys2.id) from system sys2 where sys2.uuid = sys.uuid and sys2.status = 'APPROVED'
);
update subsystem sub set latest = true where sub.id = (
select max(sub2.id) from subsystem sub2 where sub2.uuid = sub.uuid and sub2.status = 'APPROVED'
);
update discipline di set latest = true where di.id = (
select max(di2.id) from discipline di2 where di2.uuid = di.uuid and di2.status = 'APPROVED'
);
update devicegroup dg set latest = true where dg.id = (
select max(dg2.id) from devicegroup dg2 where dg2.uuid = dg.uuid and dg2.status = 'APPROVED'
);
update devicetype dt set latest = true where dt.id = (
select max(dt2.id) from devicetype dt2 where dt2.uuid = dt.uuid and dt2.status = 'APPROVED'
);
update name en set latest = true where en.id = (
select max(en2.id) from name en2 where en2.uuid = en.uuid
);
-- --------------------------------------------------------------------------------
-- foreign key
-- --------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------
-- index
-- --------------------------------------------------------------------------------
CREATE INDEX name_id_idx ON public.name (id);
CREATE INDEX name_namepartrevision_systemgroup_uuid_idx ON public.name (systemgroup_uuid);
CREATE INDEX name_namepartrevision_system_uuid_idx ON public.name (system_uuid);
CREATE INDEX name_namepartrevision_subsystem_uuid_idx ON public.name (subsystem_uuid);
CREATE INDEX name_namepartrevision_devicetype_uuid_idx ON public.name (devicetype_uuid);
CREATE INDEX name_convention_name_idx ON public.name (convention_name);
CREATE INDEX name_status_idx ON public.name (status);
CREATE INDEX name_deleted_idx ON public.name (deleted);
CREATE INDEX systemgroup_latest_idx ON public.systemgroup (latest);
CREATE INDEX system_latest_idx ON public.system (latest);
CREATE INDEX subsystem_latest_idx ON public.subsystem (latest);
CREATE INDEX discipline_latest_idx ON public.discipline (latest);
CREATE INDEX devicegroup_latest_idx ON public.devicegroup (latest);
CREATE INDEX devicetype_latest_idx ON public.devicetype (latest);
CREATE INDEX name_latest_idx ON public.name (latest);
-- --------------------------------------------------------------------------------
-- sequence
-- --------------------------------------------------------------------------------
CREATE SEQUENCE systemgroup_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE SEQUENCE system_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE SEQUENCE subsystem_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE SEQUENCE discipline_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE SEQUENCE devicegroup_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE SEQUENCE devicetype_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE SEQUENCE name_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
SELECT setval('systemgroup_id_seq', (select max(id) from systemgroup));
SELECT setval('system_id_seq', (select max(id) from "system"));
SELECT setval('subsystem_id_seq', (select max(id) from "subsystem"));
SELECT setval('discipline_id_seq', (select max(id) from discipline));
SELECT setval('devicegroup_id_seq', (select max(id) from devicegroup));
SELECT setval('devicetype_id_seq', (select max(id) from devicetype));
SELECT setval('name_id_seq', (select max(id) from "name"));
ALTER SEQUENCE systemgroup_id_seq OWNED BY systemgroup.id;
ALTER SEQUENCE system_id_seq OWNED BY system.id;
ALTER SEQUENCE subsystem_id_seq OWNED BY subsystem.id;
ALTER SEQUENCE discipline_id_seq OWNED BY discipline.id;
ALTER SEQUENCE devicegroup_id_seq OWNED BY devicegroup.id;
ALTER SEQUENCE devicetype_id_seq OWNED BY devicetype.id;
ALTER SEQUENCE name_id_seq OWNED BY name.id;
ALTER TABLE ONLY systemgroup ALTER COLUMN id SET DEFAULT nextval('systemgroup_id_seq'::regclass);
ALTER TABLE ONLY system ALTER COLUMN id SET DEFAULT nextval('system_id_seq'::regclass);
ALTER TABLE ONLY subsystem ALTER COLUMN id SET DEFAULT nextval('subsystem_id_seq'::regclass);
ALTER TABLE ONLY discipline ALTER COLUMN id SET DEFAULT nextval('discipline_id_seq'::regclass);
ALTER TABLE ONLY devicegroup ALTER COLUMN id SET DEFAULT nextval('devicegroup_id_seq'::regclass);
ALTER TABLE ONLY devicetype ALTER COLUMN id SET DEFAULT nextval('devicetype_id_seq'::regclass);
ALTER TABLE ONLY name ALTER COLUMN id SET DEFAULT nextval('name_id_seq'::regclass);
-- --------------------------------------------------------------------------------
-- primary key
-- --------------------------------------------------------------------------------
ALTER TABLE public.systemgroup ADD CONSTRAINT systemgroup_pk PRIMARY KEY (id);
ALTER TABLE public.system ADD CONSTRAINT system_pk PRIMARY KEY (id);
ALTER TABLE public.subsystem ADD CONSTRAINT subsystem_pk PRIMARY KEY (id);
ALTER TABLE public.discipline ADD CONSTRAINT discipline_pk PRIMARY KEY (id);
ALTER TABLE public.devicegroup ADD CONSTRAINT devicegroup_pk PRIMARY KEY (id);
ALTER TABLE public.devicetype ADD CONSTRAINT devicetype_pk PRIMARY KEY (id);
ALTER TABLE public.name ADD CONSTRAINT name_pk PRIMARY KEY (id);
-- --------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------
-- function
-- --------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION get_mnemonic_path_system_structure(convention_name text)
RETURNS text
LANGUAGE plpgsql
AS
$$
DECLARE
pos int;
BEGIN
pos = strpos(convention_name, ':');
IF pos > 0 THEN
RETURN substr(convention_name, 1, pos-1);
END IF;
RETURN convention_name;
END;
$$;
CREATE OR REPLACE FUNCTION get_mnemonic_path_device_structure(convention_name text)
RETURNS text
LANGUAGE plpgsql
AS
$$
DECLARE
pos int;
mnemonic_path text;
nbr_delimiters int;
BEGIN
pos = strpos(convention_name, ':');
IF pos > 0 THEN
mnemonic_path = substr(convention_name, pos+1);
nbr_delimiters = array_length(string_to_array(mnemonic_path, '-'), 1) - 1;
IF nbr_delimiters = 2 then
mnemonic_path = reverse(mnemonic_path);
mnemonic_path = substr(mnemonic_path, strpos(mnemonic_path, '-')+1);
RETURN reverse(mnemonic_path);
ELSIF nbr_delimiters = 1 then
return mnemonic_path;
ELSE
RETURN null;
END IF;
END IF;
RETURN null;
END;
$$;
CREATE OR REPLACE FUNCTION get_mnemonic_path_system(system_uuid text)
RETURNS text
LANGUAGE plpgsql
AS
$$
DECLARE
system_mnemonic text;
systemgroup_uuid text;
systemgroup_mnemonic text;
BEGIN
select parent_uuid, mnemonic into systemgroup_uuid, system_mnemonic from "system" where uuid = system_uuid and latest = true;
select mnemonic into systemgroup_mnemonic from systemgroup where uuid = systemgroup_uuid and latest = true;
if systemgroup_mnemonic is not null and system_mnemonic is not null then
return concat(systemgroup_mnemonic, '-', system_mnemonic);
elsif system_mnemonic is not null then
return system_mnemonic;
else
return null;
end if;
END;
$$;
CREATE OR REPLACE FUNCTION get_mnemonic_path_subsystem(subsystem_uuid text)
RETURNS text
LANGUAGE plpgsql
AS
$$
DECLARE
subsystem_mnemonic text;
system_uuid text;
system_mnemonic text;
systemgroup_uuid text;
systemgroup_mnemonic text;
BEGIN
select parent_uuid, mnemonic into system_uuid, subsystem_mnemonic from subsystem where uuid = subsystem_uuid and latest = true;
select parent_uuid, mnemonic into systemgroup_uuid, system_mnemonic from "system" where uuid = system_uuid and latest = true;
select mnemonic into systemgroup_mnemonic from systemgroup where uuid = systemgroup_uuid and latest = true;
if systemgroup_mnemonic is not null and system_mnemonic is not null and subsystem_mnemonic is not null then
return concat(systemgroup_mnemonic, '-', system_mnemonic, '-', subsystem_mnemonic);
elsif system_mnemonic is not null and subsystem_mnemonic is not null then
return concat(system_mnemonic, '-', subsystem_mnemonic);
elsif subsystem_mnemonic is not null then
return subsystem_mnemonic;
else
return null;
end if;
END;
$$;
CREATE OR REPLACE FUNCTION get_mnemonic_path_devicegroup(devicegroup_uuid text)
RETURNS text
LANGUAGE plpgsql
AS
$$
DECLARE
discipline_uuid text;
discipline_mnemonic text;
BEGIN
select parent_uuid into discipline_uuid from devicegroup where uuid = devicegroup_uuid and latest = true;
select mnemonic into discipline_mnemonic from discipline where uuid = discipline_uuid and latest = true;
if discipline_mnemonic is not null then
return discipline_mnemonic;
else
return null;
end if;
END;
$$;
CREATE OR REPLACE FUNCTION get_mnemonic_path_devicetype(devicetype_uuid text)
RETURNS text
LANGUAGE plpgsql
AS
$$
DECLARE
devicetype_mnemonic text;
devicegroup_uuid text;
discipline_uuid text;
discipline_mnemonic text;
BEGIN
select parent_uuid, mnemonic into devicegroup_uuid, devicetype_mnemonic from devicetype where uuid = devicetype_uuid and latest = true;
select parent_uuid, mnemonic into discipline_uuid from devicegroup where uuid = devicegroup_uuid and latest = true;
select mnemonic into discipline_mnemonic from discipline where uuid = discipline_uuid and latest = true;
if discipline_mnemonic is not null and devicetype_mnemonic is not null then
return concat(discipline_mnemonic, '-', devicetype_mnemonic);
elsif devicetype_mnemonic is not null then
return devicetype_mnemonic;
else
return null;
end if;
END;
$$;
\ No newline at end of file
SET statement_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: appinfo; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE appinfo (
id bigint NOT NULL,
version integer,
schemaversion integer NOT NULL
);
--
-- Name: appinfo_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE appinfo_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: appinfo_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE appinfo_id_seq OWNED BY appinfo.id;
--
-- Name: device; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE device (
id bigint NOT NULL,
version integer,
uuid character varying(255)
);
--
-- Name: device_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE device_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: device_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE device_id_seq OWNED BY device.id;
--
-- Name: devicerevision; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE devicerevision (
id bigint NOT NULL,
version integer,
additionalinfo character varying(255),
conventionname character varying(255),
conventionnameeqclass character varying(255),
deleted boolean NOT NULL,
instanceindex character varying(255),
requestdate timestamp without time zone,
device_id bigint,
devicetype_id bigint,
requestedby_id bigint,
section_id bigint
);
--
-- Name: devicerevision_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE devicerevision_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: devicerevision_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE devicerevision_id_seq OWNED BY devicerevision.id;
--
-- Name: namepart; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE namepart (
id bigint NOT NULL,
version integer,
nameparttype character varying(255),
uuid character varying(255)
);
--
-- Name: namepart_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE namepart_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: namepart_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE namepart_id_seq OWNED BY namepart.id;
--
-- Name: namepartrevision; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE namepartrevision (
id bigint NOT NULL,
version integer,
deleted boolean NOT NULL,
description character varying(255),
mnemonic character varying(255),
mnemoniceqclass character varying(255),
name character varying(255),
processdate timestamp without time zone,
processorcomment character varying(255),
requestdate timestamp without time zone,
requestercomment character varying(255),
status character varying(255),
namepart_id bigint,
parent_id bigint,
processedby_id bigint,
requestedby_id bigint
);
--
-- Name: namepartrevision_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE namepartrevision_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: namepartrevision_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE namepartrevision_id_seq OWNED BY namepartrevision.id;
--
-- Name: useraccount; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE useraccount (
id bigint NOT NULL,
version integer,
role character varying(255),
username character varying(255)
);
--
-- Name: useraccount_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE useraccount_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: useraccount_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE useraccount_id_seq OWNED BY useraccount.id;
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY appinfo ALTER COLUMN id SET DEFAULT nextval('appinfo_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY device ALTER COLUMN id SET DEFAULT nextval('device_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY devicerevision ALTER COLUMN id SET DEFAULT nextval('devicerevision_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY namepart ALTER COLUMN id SET DEFAULT nextval('namepart_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY namepartrevision ALTER COLUMN id SET DEFAULT nextval('namepartrevision_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY useraccount ALTER COLUMN id SET DEFAULT nextval('useraccount_id_seq'::regclass);
--
-- Name: appinfo_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY appinfo
ADD CONSTRAINT appinfo_pkey PRIMARY KEY (id);
--
-- Name: device_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY device
ADD CONSTRAINT device_pkey PRIMARY KEY (id);
--
-- Name: devicerevision_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY devicerevision
ADD CONSTRAINT devicerevision_pkey PRIMARY KEY (id);
--
-- Name: namepart_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY namepart
ADD CONSTRAINT namepart_pkey PRIMARY KEY (id);
--
-- Name: namepartrevision_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY namepartrevision
ADD CONSTRAINT namepartrevision_pkey PRIMARY KEY (id);
--
-- Name: useraccount_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY useraccount
ADD CONSTRAINT useraccount_pkey PRIMARY KEY (id);
--
-- Name: fk_3f26vetemhujfdm9q74ecr2u5; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY namepartrevision
ADD CONSTRAINT fk_3f26vetemhujfdm9q74ecr2u5 FOREIGN KEY (namepart_id) REFERENCES namepart(id);
--
-- Name: fk_4ucnoos7kd8s1gaqbpwm1xptq; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY devicerevision
ADD CONSTRAINT fk_4ucnoos7kd8s1gaqbpwm1xptq FOREIGN KEY (requestedby_id) REFERENCES useraccount(id);
--
-- Name: fk_9vomfk9x1jow27ifx6xc62c5x; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY namepartrevision
ADD CONSTRAINT fk_9vomfk9x1jow27ifx6xc62c5x FOREIGN KEY (processedby_id) REFERENCES useraccount(id);
--
-- Name: fk_9xs5oy86lf0j8ukpjokjipeke; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY namepartrevision
ADD CONSTRAINT fk_9xs5oy86lf0j8ukpjokjipeke FOREIGN KEY (requestedby_id) REFERENCES useraccount(id);
--
-- Name: fk_d3ocbsb4tl4ttnusn98khq148; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY devicerevision
ADD CONSTRAINT fk_d3ocbsb4tl4ttnusn98khq148 FOREIGN KEY (devicetype_id) REFERENCES namepart(id);
--
-- Name: fk_l7kklb4mxixjs27nsso6shone; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY devicerevision
ADD CONSTRAINT fk_l7kklb4mxixjs27nsso6shone FOREIGN KEY (section_id) REFERENCES namepart(id);
--
-- Name: fk_l9r1givkfaiol5or2lnr324xp; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY devicerevision
ADD CONSTRAINT fk_l9r1givkfaiol5or2lnr324xp FOREIGN KEY (device_id) REFERENCES device(id);
--
-- Name: fk_lufxqy46l9eiq55d445rbukag; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY namepartrevision
ADD CONSTRAINT fk_lufxqy46l9eiq55d445rbukag FOREIGN KEY (parent_id) REFERENCES namepart(id);
--
-- Name: public; Type: ACL; Schema: -; Owner: -
--
REVOKE ALL ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON SCHEMA public FROM postgres;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO PUBLIC;
INSERT INTO appinfo (version, schemaversion) VALUES (1,1);
......@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<version>2.7.18</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.openepics</groupId>
......@@ -15,83 +15,115 @@
<description>Naming backend Spring Boot</description>
<properties>
<java.version>17</java.version>
<jacoco.skip>true</jacoco.skip>
<skipITs>true</skipITs>
<skipITCoverage>true</skipITCoverage>
</properties>
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.2.0-jre</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>findbugs-annotations</artifactId>
<version>3.0.1</version>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-security</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>io.fusionauth</groupId>
<artifactId>fusionauth-jwt</artifactId>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.6</version>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-annotations</artifactId>
<version>4.8.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<version>0.8.12</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.16.3</version>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.16.3</version>
<version>1.19.8</version>
<scope>test</scope>
</dependency>
</dependencies>
......@@ -101,6 +133,110 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes/static/pdfs</outputDirectory>
<resources>
<resource>
<directory>docs/about</directory>
<includes>
<include>naming_rest_api_brief_introduction.pdf</include>
<include>naming_rest_api_cheat_sheet.pdf</include>
<include>naming_rest_api_excel_guide.pdf</include>
<include>naming_rest_api_migration.pdf</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipITs>${skipITs}</skipITs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<classifier>runtime</classifier>
<outputDirectory>${project.build.directory}/jacoco</outputDirectory>
<destFileName>jacocoagent.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>merge</id>
<phase>verify</phase>
<goals>
<goal>merge</goal>
</goals>
<configuration>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<includes>
<include>jacoco*.exec</include>
</includes>
</fileSet>
</fileSets>
<destFile>${project.build.directory}/site/jacoco/jacoco.exec</destFile>
</configuration>
</execution>
<execution>
<id>report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/site/jacoco/jacoco.exec</dataFile>
<outputDirectory>${project.build.directory}/site/jacoco</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
......@@ -18,9 +18,24 @@
package org.openepics.names;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
/**
* Starting point of SpringBoot application.
*
* @author Lars Johansson
*/
@SpringBootApplication
public class NamingApplication {
......@@ -28,4 +43,44 @@ public class NamingApplication {
SpringApplication.run(NamingApplication.class, args);
}
@Value("${openapi.externaldocs.description}") String openapiExternaldocsDescription;
@Value("${openapi.externaldocs.url}") String openapiExternaldocsUrl;
@Value("${openapi.info.contact.email}") String openapiInfoContactEmail;
@Value("${openapi.info.contact.name}") String openapiInfoContactName;
@Value("${openapi.info.contact.url}") String openapiInfoContactUrl;
@Value("${openapi.info.description}") String openapiInfoDescription;
@Value("${openapi.info.license.name}") String openapiInfoLicenseName;
@Value("${openapi.info.title}") String openapiInfoTitle;
@Bean
public OpenAPI customOpenAPI(@Value("${app.version}") String appVersion) {
return new OpenAPI()
.externalDocs(new ExternalDocumentation()
.description(openapiExternaldocsDescription)
.url(openapiExternaldocsUrl))
.info(new Info()
.contact(new Contact()
.email(openapiInfoContactEmail)
.name(openapiInfoContactName)
.url(openapiInfoContactUrl))
.description(openapiInfoDescription)
.license(new License().name(openapiInfoLicenseName))
.title(openapiInfoTitle)
.version(appVersion));
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedOriginPatterns("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE");
}
};
}
}
/*
* Copyright (C) 2023 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.configuration;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
/**
* Set up email configuration for Naming backend.
*
* @author Lars Johansson
*/
@Configuration
public class MailConfiguration {
@Value("${naming.smtp.host}")
String namingSmtpHost;
@Value("${naming.smtp.port}")
int namingSmtpPort;
@Value("${naming.smtp.username}")
String namingSmtpUsername;
@Value("${naming.smtp.password}")
String namingSmtpPassword;
@Value("${spring.mail.properties.mail.smtp.auth}")
String springMailPropertiesMailSmtpAuth;
@Value("${spring.mail.properties.mail.smtp.starttls.enable}")
String springMailPropertiesMailSmtpStarttlsEnable;
@Value("${spring.mail.properties.mail.smtp.connectiontimeout}")
String springMailPropertiesMailSmtpConnectiontimeout;
@Value("${spring.mail.properties.mail.smtp.timeout}")
String springMailPropertiesMailSmtpTimeout;
@Value("${spring.mail.properties.mail.smtp.writetimeout}")
String springMailPropertiesMailSmtpWritetimeout;
@Value("${spring.mail.debug}")
String springMailDebug;
/**
* Set up email configuration with sender.
*/
@Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost(namingSmtpHost);
mailSender.setPort(namingSmtpPort);
mailSender.setUsername(namingSmtpUsername);
mailSender.setPassword(namingSmtpPassword);
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", springMailPropertiesMailSmtpAuth);
props.put("mail.smtp.starttls.enable", springMailPropertiesMailSmtpStarttlsEnable);
props.put("mail.smtp.connectiontimeout", springMailPropertiesMailSmtpConnectiontimeout);
props.put("mail.smtp.timeout", springMailPropertiesMailSmtpTimeout);
props.put("mail.smtp.writetimeout", springMailPropertiesMailSmtpTimeout);
props.put("mail.debug", springMailDebug);
return mailSender;
}
}
/*
* Copyright (C) 2024 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.configuration;
import java.util.Arrays;
import java.util.List;
import org.openepics.names.rest.filter.JwtRequestFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.http.HttpMethod;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
import com.google.common.collect.ImmutableList;
/**
* Set up security configuration for Naming backend.
*
* @author Lars Johansson
*/
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = false)
public class SecurityConfiguration {
// note
// ability to run application with and without security
// spring and swagger work together
// spring
// @EnableMethodSecurity
// @PreAuthorize
// +
// AuthorizationManagerBeforeMethodInterceptor
// SecurityFilterChain
// swagger
// @SecurityRequirement
private static final String API_V1_AUTHENTICATION = "/api/v1/authentication";
private static final String API_V1_NAMES = "/api/v1/names";
private static final String API_V1_NAMES_PATHS = "/api/v1/names/*";
private static final String API_V1_STRUCTURES = "/api/v1/structures";
private static final String API_V1_STRUCTURES_PATHS = "/api/v1/structures/*";
private static final String API_V1_PV_NAMES = "/api/v1/pvNames";
private static final String API_V1_CONVERT = "/api/v1/convert";
private static final String ACTUATOR = "/actuator";
private static final String ACTUATOR_PATHS = "/actuator/**";
private static final String HEALTHCHECK = "/healthcheck";
private static final String REPORT_PATHS = "/report/**";
public static final String ROLE_ADMINISTRATOR = "NamingAdministrator";
public static final String ROLE_USER = "NamingUser";
public static final String IS_ADMINISTRATOR = "hasAuthority('" + ROLE_ADMINISTRATOR + "')";
public static final String IS_USER = "hasAuthority('" + ROLE_USER + "')";
public static final String IS_ADMINISTRATOR_OR_USER = IS_ADMINISTRATOR + " or " + IS_USER;
private static final List<String> ALLOWED_ROLES_TO_LOGIN =
Arrays.asList(
SecurityConfiguration.ROLE_ADMINISTRATOR,
SecurityConfiguration.ROLE_USER);
@Value("${naming.security.enabled:false}")
private boolean namingSecurityEnabled;
@Value("${springdoc.api-docs.path}")
private String apiDocsPath;
@Value("${springdoc.swagger-ui.path}")
private String swaggerUiPath;
private final UserDetailsService jwtUserDetailsService;
private final JwtRequestFilter jwtRequestFilter;
@Autowired
public SecurityConfiguration(
UserDetailsService jwtUserDetailsService,
JwtRequestFilter jwtRequestFilter) {
this.jwtUserDetailsService = jwtUserDetailsService;
this.jwtRequestFilter = jwtRequestFilter;
}
public static List<String> getAllowedRolesToLogin() {
return ImmutableList.copyOf(ALLOWED_ROLES_TO_LOGIN);
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@ConditionalOnProperty(name = "naming.security.enabled", havingValue = "true")
static AuthorizationManagerBeforeMethodInterceptor preAuthorizeAuthorizationMethodInterceptor() {
return AuthorizationManagerBeforeMethodInterceptor.preAuthorize();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(jwtUserDetailsService);
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// disable csrf since internal
// authentication and authorization
// create, read, update, delete
// not needed for read but needed for others, user for names, admin for structures
// accept requests to
// openapi, swagger
// healthcheck
// login, logout
// patterns that are not mentioned are to be authenticated
// stateless session as session not used to store user's state
// TODO naming-convention-tool
// about
// paths to be removed when such functionality is removed
// /verification to verify data migration
// /rest rest api for comparison
// paths
// /verification/**
// /rest/deviceNames/**
// /rest/healthcheck
// /rest/history/**
// /rest/parts/**
http
.csrf().disable()
.cors();
if (namingSecurityEnabled) {
http
.authorizeRequests()
// api docs, swagger
// authentication - login, logout
// names - read
// structures - read
// other
.mvcMatchers("/v3/api-docs/**", apiDocsPath + "/**", "/api/swagger-ui/**", "/swagger-ui/**", swaggerUiPath).permitAll()
.mvcMatchers(HttpMethod.POST, API_V1_AUTHENTICATION + "/login").permitAll()
.mvcMatchers(HttpMethod.GET, API_V1_NAMES, API_V1_NAMES_PATHS).permitAll()
.mvcMatchers(HttpMethod.GET, API_V1_STRUCTURES, API_V1_STRUCTURES_PATHS).permitAll()
.mvcMatchers(HttpMethod.GET, API_V1_PV_NAMES).permitAll()
.mvcMatchers(HttpMethod.GET, API_V1_CONVERT).permitAll()
.mvcMatchers(HttpMethod.GET, REPORT_PATHS).permitAll()
.mvcMatchers(HttpMethod.GET, HEALTHCHECK).permitAll()
.mvcMatchers(HttpMethod.GET, ACTUATOR, ACTUATOR_PATHS).permitAll()
// naming-convention-tool
.mvcMatchers(HttpMethod.GET, "/verification/**").permitAll()
.mvcMatchers(HttpMethod.GET, "/rest/deviceNames/**").permitAll()
.mvcMatchers(HttpMethod.GET, "/rest/healthcheck").permitAll()
.mvcMatchers(HttpMethod.GET, "/rest/history/**").permitAll()
.mvcMatchers(HttpMethod.GET, "/rest/parts/**").permitAll()
// any other requests to be authenticated
.anyRequest().authenticated()
// add a filter to validate the tokens with every request
.and()
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
// make sure we use stateless session; session won't be used to store user's state.
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
// allow % that is URL encoded %25 may be in path
// see org.springframework.security.web.firewall.StrictHttpFirewall
return web -> web.httpFirewall(allowUrlEncodedPercenthHttpFirewall());
}
private HttpFirewall allowUrlEncodedPercenthHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedPercent(true);
return firewall;
}
}
/*
* Copyright (C) 2024 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.configuration;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import io.swagger.v3.oas.annotations.security.SecuritySchemes;
/**
* Set up Swagger configuration for Naming backend.
*
* @author Lars Johansson
*/
@Configuration
@SecuritySchemes(value = {
@SecurityScheme(
name = "bearerAuth",
type = SecuritySchemeType.HTTP,
in = SecuritySchemeIn.HEADER,
bearerFormat = "JWT",
scheme = "bearer")
})
public class SwaggerConfiguration {
@Bean
public GroupedOpenApi v1Api() {
return GroupedOpenApi.builder().group("api-v1").pathsToMatch("/api/v1/**").build();
}
@Bean
public GroupedOpenApi base() {
return GroupedOpenApi.builder().group("base").pathsToMatch("/report/**", "/healthcheck").build();
}
}
/*
* Copyright (C) 2022 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.exception;
/**
* Exception class to assist in handling of service layer exceptions.
*
* @author Lars Johansson
*/
public class DataConflictException extends ServiceException {
/**
*
*/
private static final long serialVersionUID = 717292299575574858L;
/**
* Public constructor.
*
* @param message message
* @param details details
* @param field field
*/
public DataConflictException(String message, String details, String field) {
super(message, details, field, null);
}
}
/*
* Copyright (C) 2022 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.exception;
/**
* Exception class to assist in handling of service layer exceptions.
*
* @author Lars Johansson
*/
public class DataDeletedException extends ServiceException {
/**
*
*/
private static final long serialVersionUID = 8214965988959148282L;
/**
* Public constructor.
*
* @param message message
* @param details details
* @param field field
*/
public DataDeletedException(String message, String details, String field) {
super(message, details, field, null);
}
}
/*
* Copyright (C) 2022 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.exception;
/**
* Exception class to assist in handling of service layer exceptions.
*
* @author Lars Johansson
*/
public class DataExistException extends ServiceException {
/**
*
*/
private static final long serialVersionUID = -3192828921283195697L;
/**
* Public constructor.
*
* @param message message
* @param details details
* @param field field
*/
public DataExistException(String message, String details, String field) {
super(message, details, field, null);
}
}
/*
* Copyright (C) 2022 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.exception;
/**
* Exception class to assist in handling of service layer exceptions.
*
* @author Lars Johansson
*/
public class DataNotAvailableException extends ServiceException {
/**
*
*/
private static final long serialVersionUID = 771292348691428745L;
/**
* Public constructor.
*
* @param message message
* @param details details
* @param field field
*/
public DataNotAvailableException(String message, String details, String field) {
super(message, details, field, null);
}
}
/*
* Copyright (C) 2022 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.exception;
/**
* Exception class to assist in handling of service layer exceptions.
*
* @author Lars Johansson
*/
public class DataNotCorrectException extends ServiceException {
/**
*
*/
private static final long serialVersionUID = 3525813299369253195L;
/**
* Public constructor.
*
* @param message message
* @param details details
* @param field field
*/
public DataNotCorrectException(String message, String details, String field) {
super(message, details, field, null);
}
}
/*
* Copyright (C) 2022 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.exception;
/**
* Exception class to assist in handling of service layer exceptions.
*
* @author Lars Johansson
*/
public class DataNotFoundException extends ServiceException {
/**
*
*/
private static final long serialVersionUID = -3908854009422708172L;
/**
* Public constructor.
*
* @param message message
* @param details details
* @param field field
*/
public DataNotFoundException(String message, String details, String field) {
super(message, details, field, null);
}
}
/*
* Copyright (C) 2022 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.exception;
/**
* Exception class to assist in handling of service layer exceptions.
*
* @author Lars Johansson
*/
public class DataNotValidException extends ServiceException {
/**
*
*/
private static final long serialVersionUID = -1203854671942406300L;
/**
* Public constructor.
*
* @param message message
* @param details details
* @param field field
*/
public DataNotValidException(String message, String details, String field) {
super(message, details, field, null);
}
}
/*
* Copyright (C) 2022 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.openepics.names.exception;
/**
* Exception class to assist in handling of service layer exceptions.
*
* @author Lars Johansson
*/
public class InputNotAvailableException extends ServiceException {
/**
*
*/
private static final long serialVersionUID = 2223786874114860161L;
/**
* Public constructor.
*
* @param message message
* @param details details
* @param field field
*/
public InputNotAvailableException(String message, String details, String field) {
super(message, details, field, null);
}
}