aboutsummaryrefslogtreecommitdiffstats
path: root/ecd-app-common
diff options
context:
space:
mode:
Diffstat (limited to 'ecd-app-common')
-rw-r--r--ecd-app-common/.gitignore8
-rw-r--r--ecd-app-common/README.md10
-rw-r--r--ecd-app-common/db-scripts/README.md23
-rw-r--r--ecd-app-common/db-scripts/ecd-ddl-postgres-1707-common.sql531
-rw-r--r--ecd-app-common/db-scripts/ecd-dml-postgres-1707-common.sql446
-rw-r--r--ecd-app-common/pom.xml256
-rw-r--r--ecd-app-common/src/main/java/org/onap/fusionapp/model/Result.java53
-rw-r--r--ecd-app-common/src/main/java/org/onap/fusionapp/service/AdminAuthExtension.java42
-rw-r--r--ecd-app-common/src/main/java/org/onap/fusionapp/util/CustomLoggingFilter.java58
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/CloudifyController.java650
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/ConsulController.java455
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/DashboardHomeController.java157
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/DashboardRestrictedBaseController.java266
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/ECDSingleSignOnController.java277
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/HealthCheckController.java86
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/domain/ControllerEndpoint.java71
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprint.java61
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintContent.java44
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintList.java62
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintUpload.java55
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeployment.java161
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeploymentList.java62
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeploymentRequest.java64
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecution.java73
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecutionList.java62
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecutionRequest.java68
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulDatacenter.java44
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulHealthServiceRegistration.java116
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulNodeInfo.java72
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceHealth.java82
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceHealthHistory.java54
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceInfo.java53
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ControllerEndpointCredentials.java102
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ControllerEndpointTransport.java65
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ECTransportModel.java63
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/HealthStatus.java53
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponseError.java93
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponsePage.java75
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponseSuccess.java57
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientImpl.java425
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientMockImpl.java310
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/HttpComponentsClientHttpRequestFactoryBasicAuth.java71
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/IControllerRestClient.java248
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/service/ControllerEndpointService.java59
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/service/ControllerEndpointServiceImpl.java76
-rw-r--r--ecd-app-common/src/main/java/org/onap/oom/dashboard/util/DashboardProperties.java154
-rw-r--r--ecd-app-common/src/test/java/org/onap/fusion/core/MockApplicationContextTestSuite.java137
-rw-r--r--ecd-app-common/src/test/java/org/onap/fusionapp/SanityTest.java41
-rw-r--r--ecd-app-common/src/test/java/org/onap/fusionapp/service/ProfileServiceTest.java58
49 files changed, 6609 insertions, 0 deletions
diff --git a/ecd-app-common/.gitignore b/ecd-app-common/.gitignore
new file mode 100644
index 0000000..6a47a7c
--- /dev/null
+++ b/ecd-app-common/.gitignore
@@ -0,0 +1,8 @@
+.classpath
+.project
+.settings/
+/bin/
+/target/
+/catalina.base_IS_UNDEFINED/
+/debug-logs/
+/logs/
diff --git a/ecd-app-common/README.md b/ecd-app-common/README.md
new file mode 100644
index 0000000..3bb1a66
--- /dev/null
+++ b/ecd-app-common/README.md
@@ -0,0 +1,10 @@
+# ONAP Operations Manager Dashboard
+
+## Overview
+
+The ONAP Operations Manager Dashboard provides a front-end GUI to view and
+manage executions (virtual machines) inside the ONAP Operations Manager (OOM).
+
+This application is based on the ONAP Portal SDK. Use Apache Maven to build
+and package this webapp for deployment. See the file ecd-app-deployment-guide.txt
+for complete details.
diff --git a/ecd-app-common/db-scripts/README.md b/ecd-app-common/db-scripts/README.md
new file mode 100644
index 0000000..474e438
--- /dev/null
+++ b/ecd-app-common/db-scripts/README.md
@@ -0,0 +1,23 @@
+# ECOMP-C Dashboard Database Scripts
+
+This directory has a DDL to create tables and and DML scripts to populate tables
+in Postgresql for the ECOMP-C Dashboard web application.
+
+## Internal deployments
+
+To create a database for internal use:
+- Run the common DDL script
+- Run the common DML script
+- Run the internal-use-only DML script, which can be found in a different project
+
+## Open-source deployments
+
+To create a database for ONAP use:
+- Run the common DDL script
+- Run the common DML script
+
+## Notes on Postgresql:
+
+Set default schema for user:
+ ALTER USER <the-user-name> SET search_path to <the-schema-name>;
+ (the above statement is not needed for version 9.4 and above) \ No newline at end of file
diff --git a/ecd-app-common/db-scripts/ecd-ddl-postgres-1707-common.sql b/ecd-app-common/db-scripts/ecd-ddl-postgres-1707-common.sql
new file mode 100644
index 0000000..c9f9e42
--- /dev/null
+++ b/ecd-app-common/db-scripts/ecd-ddl-postgres-1707-common.sql
@@ -0,0 +1,531 @@
+-- ---------------------------------------------------------------------------------------------------------------
+-- This script creates tables for the ECOMP Controller Dashboard web app.
+-- in the 1707 release, same tables for both internal and external use.
+-- ------------------------------------------------------------------------------------------------------------------
+CREATE SCHEMA (schema name);
+
+SET SEARCH_PATH = (schema name);
+
+create table fn_lu_timezone (
+ timezone_id serial primary key,
+ timezone_name character varying(100) not null,
+ timezone_value character varying(100) not null
+);
+
+-- this sequence is named in Fusion.hbm.xml
+create sequence seq_fn_user;
+create table fn_user (
+ user_id serial primary key,
+ org_id int,
+ manager_id int,
+ first_name character varying(25),
+ middle_name character varying(25),
+ last_name character varying(25),
+ phone character varying(25),
+ fax character varying(25),
+ cellular character varying(25),
+ email character varying(50),
+ address_id int,
+ alert_method_cd character varying(10),
+ hrid character varying(20),
+ org_user_id character varying(20),
+ org_code character varying(30),
+ login_id character varying(25),
+ login_pwd character varying(25),
+ last_login_date timestamp,
+ active_yn character varying(1) default 'y' not null,
+ created_id int,
+ created_date timestamp default now(),
+ modified_id int,
+ modified_date timestamp default now(),
+ is_internal_yn character(1) default 'n' not null,
+ address_line_1 character varying(100),
+ address_line_2 character varying(100),
+ city character varying(50),
+ state_cd character varying(3),
+ zip_code character varying(11),
+ country_cd character varying(3),
+ location_clli character varying(8),
+ org_manager_userid character varying(6),
+ company character varying(100),
+ department_name character varying(100),
+ job_title character varying(100),
+ timezone int,
+ department character varying(25),
+ business_unit character varying(25),
+ business_unit_name character varying(100),
+ cost_center character varying(25),
+ fin_loc_code character varying(10),
+ silo_status character varying(10)
+);
+
+-- this sequence is named in Fusion.hbm.xml
+create sequence seq_fn_role;
+create table fn_role (
+ role_id serial primary key,
+ role_name character varying(50) not null,
+ active_yn character varying(1) default 'y' not null,
+ priority numeric(4,0)
+);
+
+create table fn_audit_action (
+ audit_action_id integer primary key,
+ class_name character varying(500) not null,
+ method_name character varying(50) not null,
+ audit_action_cd character varying(20) not null,
+ audit_action_desc character varying(200),
+ active_yn character varying(1)
+);
+
+create table fn_audit_action_log (
+ audit_log_id serial primary key,
+ audit_action_cd character varying(200),
+ action_time timestamp,
+ user_id int,
+ class_name character varying(100),
+ method_name character varying(50),
+ success_msg character varying(20),
+ error_msg character varying(500)
+);
+
+create table fn_lu_activity (
+ activity_cd character varying(50) not null primary key,
+ activity character varying(50) not null
+);
+
+-- this sequence is named in Fusion.hbm.xml
+create sequence seq_fn_audit_log;
+create table fn_audit_log (
+ log_id serial primary key,
+ user_id int not null,
+ activity_cd character varying(50) not null,
+ audit_date timestamp default now() not null,
+ comments character varying(1000),
+ affected_record_id_bk character varying(500),
+ affected_record_id character varying(4000),
+ constraint fk_fn_audit_ref_209_fn_user foreign key (user_id) references fn_user(user_id)
+);
+
+create table fn_datasource (
+ id serial primary key,
+ name character varying(50),
+ driver_name character varying(256),
+ server character varying(256),
+ port integer,
+ user_name character varying(256),
+ password character varying(256),
+ url character varying(256),
+ min_pool_size integer,
+ max_pool_size integer,
+ adapter_id integer,
+ ds_type character varying(20)
+);
+
+create table fn_function (
+ function_cd character varying(30) not null primary key,
+ function_name character varying(50) not null
+);
+
+create table fn_lu_alert_method (
+ alert_method_cd character varying(10) not null,
+ alert_method character varying(50) not null
+);
+
+create table fn_lu_broadcast_site (
+ broadcast_site_cd character varying(50) not null,
+ broadcast_site_descr character varying(100)
+);
+
+create table fn_lu_call_times (
+ call_time_id int not null,
+ call_time_amount int not null,
+ call_time_display character varying(50) not null
+);
+
+create table fn_lu_city (
+ city_cd character varying(2) not null,
+ city character varying(100) not null,
+ state_cd character varying(2) not null,
+ primary key (city_cd, state_cd)
+);
+
+create table fn_lu_country (
+ country_cd character varying(3) not null primary key,
+ country character varying(100) not null,
+ full_name character varying(100),
+ webphone_country_label character varying(30)
+);
+
+create table fn_lu_menu_set (
+ menu_set_cd character varying(10) not null primary key,
+ menu_set_name character varying(50) not null
+);
+
+create table fn_lu_priority (
+ priority_id int not null,
+ priority character varying(50) not null,
+ active_yn character(1) not null,
+ sort_order numeric(5,0)
+);
+
+create table fn_lu_role_type (
+ role_type_id int not null,
+ role_type character varying(50) not null
+);
+
+create table fn_lu_state (
+ state_cd character varying(2) not null,
+ state character varying(100) not null
+);
+
+create table fn_lu_tab_set (
+ tab_set_cd character varying(30) not null,
+ tab_set_name character varying(50) not null
+);
+
+-- this sequence is named in Fusion.hbm.xml
+create sequence seq_fn_menu;
+create table fn_menu (
+ menu_id serial primary key,
+ label character varying(100),
+ parent_id int,
+ sort_order numeric(4,0),
+ action character varying(200),
+ function_cd character varying(30),
+ active_yn character varying(1) default 'y' not null,
+ servlet character varying(50),
+ query_string character varying(200),
+ external_url character varying(200),
+ target character varying(25),
+ menu_set_cd character varying(10) default 'app',
+ separator_yn character(1) default 'n',
+ image_src character varying(100),
+ constraint fk_fn_menu_ref_196_fn_menu foreign key (parent_id) references fn_menu(menu_id),
+ constraint fk_fn_menu_menu_set_cd foreign key (menu_set_cd) references fn_lu_menu_set(menu_set_cd),
+ constraint fk_fn_menu_ref_223_fn_funct foreign key (function_cd) references fn_function(function_cd)
+);
+
+create table fn_org (
+ org_id int not null,
+ org_name character varying(50) not null,
+ access_cd character varying(10)
+);
+
+create table fn_restricted_url (
+ restricted_url character varying(250) not null,
+ function_cd character varying(30) not null
+);
+
+create table fn_role_composite (
+ parent_role_id int not null,
+ child_role_id int not null,
+ constraint fk_fn_role_composite_child foreign key (child_role_id) references fn_role(role_id),
+ constraint fk_fn_role_composite_parent foreign key (parent_role_id) references fn_role(role_id)
+);
+
+create table fn_role_function (
+ role_id int not null,
+ function_cd character varying(30) not null,
+ constraint fk_fn_role__ref_198_fn_role foreign key (role_id) references fn_role(role_id)
+);
+
+create table fn_tab (
+ tab_cd character varying(30) not null,
+ tab_name character varying(50) not null,
+ tab_descr character varying(100),
+ action character varying(100) not null,
+ function_cd character varying(30) not null,
+ active_yn character(1) not null,
+ sort_order int not null,
+ parent_tab_cd character varying(30),
+ tab_set_cd character varying(30)
+);
+
+create table fn_tab_selected (
+ selected_tab_cd character varying(30) not null,
+ tab_uri character varying(40) not null
+);
+
+create table fn_user_pseudo_role (
+ pseudo_role_id int not null,
+ user_id int not null
+);
+
+create table fn_user_role (
+ user_id int not null,
+ role_id int not null,
+ priority numeric(4,0),
+ app_id int default 1,
+ constraint fk_fn_user__ref_172_fn_user foreign key (user_id) references fn_user(user_id),
+ constraint fk_fn_user__ref_175_fn_role foreign key (role_id) references fn_role(role_id)
+);
+
+create table fn_xmltype (
+ id int not null,
+ xml_document text
+);
+
+create table schema_info (
+ schema_id character varying(25) not null,
+ schema_desc character varying(75) not null,
+ datasource_type character varying(100),
+ connection_url varchar(200) not null,
+ user_name varchar(45) not null,
+ password varchar(45) null default null,
+ driver_class varchar(100) not null,
+ min_pool_size int not null,
+ max_pool_size int not null,
+ idle_connection_test_period int not null
+);
+
+create table fn_app (
+ app_id serial primary key,
+ app_name varchar(100) not null default '?',
+ app_image_url varchar(256) default null,
+ app_description varchar(512) default null,
+ app_notes varchar(4096) default null,
+ app_url varchar(256) default null,
+ app_alternate_url varchar(256) default null,
+ app_rest_endpoint varchar(2000) default null,
+ ml_app_name varchar(50) not null default '?',
+ ml_app_admin_id varchar(7) not null default '?',
+ mots_id int default null,
+ app_password varchar(256) not null default '?',
+ open char(1) default 'n',
+ enabled char(1) default 'y',
+ thumbnail bytea,
+ app_username varchar(50),
+ ueb_key varchar(256) default null,
+ ueb_secret varchar(256) default null,
+ ueb_topic_name varchar(256) default null
+);
+
+create table fn_workflow (
+ id serial primary key,
+ name varchar(20) NOT NULL unique,
+ description varchar(500) DEFAULT NULL,
+ run_link varchar(300) DEFAULT NULL,
+ suspend_link varchar(300) DEFAULT NULL,
+ modified_link varchar(300) DEFAULT NULL,
+ active_yn varchar(300) DEFAULT NULL,
+ created varchar(300) DEFAULT NULL,
+ created_by int DEFAULT NULL,
+ modified varchar(300) DEFAULT NULL,
+ modified_by int DEFAULT NULL,
+ workflow_key varchar(50) DEFAULT NULL
+);
+
+create table fn_schedule_workflows (
+ id_schedule_workflows serial primary key,
+ workflow_server_url varchar(45) default null,
+ workflow_key varchar(45) not null,
+ workflow_arguments varchar(45) default null,
+ startdatetimecron varchar(45) default null,
+ enddatetime timestamp default now(),
+ start_date_time timestamp default now(),
+ recurrence varchar(45) default null
+ );
+
+create table fn_license (
+ id int not null,
+ app_id int not null,
+ ip_address character varying(100) not null,
+ quantum_version_id int not null,
+ created_date timestamp default now(),
+ modified_date timestamp default now(),
+ created_id int,
+ modified_id int,
+ end_date timestamp default '2036-01-19 03:14:07'
+);
+
+create table fn_license_app (
+ id int not null,
+ app_name character varying(100) not null,
+ ctxt_name character varying(100)
+);
+
+create table fn_license_contact (
+ id int not null,
+ license_id integer,
+ sbcid character varying(20)
+);
+
+create table fn_license_history (
+ id int not null,
+ license_id int,
+ app_id int,
+ ip_address character varying(100),
+ quantum_version_id int,
+ created_date timestamp default now(),
+ modified_date timestamp default now(),
+ created_id int,
+ modified_id int
+);
+
+create table fn_license_version (
+ id int not null,
+ quantum_version character varying(25)
+);
+
+create table fn_lu_message_location (
+ message_location_id int primary key,
+ message_location_descr character varying(30) not null
+);
+
+create table ecd_endpoint (
+ user_id int not null primary key,
+ name character varying(64),
+ url character varying(512)
+);
+
+alter table ecd_endpoint
+ add constraint fk_ecd_endpoint_ref_fn_user foreign key (user_id) references fn_user(user_id);
+
+create view v_url_access as
+ select distinct m.action as url,
+ m.function_cd
+ from fn_menu m
+ where (m.action is not null)
+union
+ select distinct t.action as url,
+ t.function_cd
+ from fn_tab t
+ where (t.action is not null)
+union
+ select r.restricted_url as url,
+ r.function_cd
+ from fn_restricted_url r;
+
+alter table fn_audit_log
+ add constraint fk_fn_audit_ref_205_fn_lu_ac foreign key (activity_cd) references fn_lu_activity(activity_cd);
+
+alter table fn_role_function
+ add constraint fk_fn_role__ref_201_fn_funct foreign key (function_cd) references fn_function(function_cd);
+
+alter table fn_lu_alert_method
+ add constraint fn_lu_alert_method_alert_method_cd primary key (alert_method_cd);
+
+alter table fn_lu_broadcast_site
+ add constraint fn_lu_broadcast_site_broadcast_site_cd primary key (broadcast_site_cd);
+
+alter table fn_lu_call_times
+ add constraint fn_lu_call_times_call_time_id primary key (call_time_id);
+
+alter table fn_lu_priority
+ add constraint fn_lu_priority_priority_id primary key (priority_id);
+
+alter table fn_lu_role_type
+ add constraint fn_lu_role_type_role_type_id primary key (role_type_id);
+
+alter table fn_lu_state
+ add constraint fn_lu_state_state_cd primary key (state_cd);
+
+alter table fn_lu_tab_set
+ add constraint fn_lu_tab_set_tab_set_cd primary key (tab_set_cd);
+
+alter table fn_org
+ add constraint fn_org_org_id primary key (org_id);
+
+alter table fn_restricted_url
+ add constraint fn_restricted_url_restricted_urlfunction_cd primary key (restricted_url, function_cd);
+
+alter table fn_role_composite
+ add constraint fn_role_composite_parent_role_idchild_role_id primary key (parent_role_id, child_role_id);
+
+alter table fn_role_function
+ add constraint fn_role_function_role_idfunction_cd primary key (role_id, function_cd);
+
+alter table fn_tab
+ add constraint fn_tab_tab_cd primary key (tab_cd);
+
+alter table fn_tab_selected
+ add constraint fn_tab_selected_selected_tab_cdtab_uri primary key (selected_tab_cd, tab_uri);
+
+alter table fn_user_pseudo_role
+ add constraint fn_user_pseudo_role_pseudo_role_iduser_id primary key (pseudo_role_id, user_id);
+
+alter table fn_user_role
+ add constraint fn_user_role_user_idrole_id primary key (user_id, role_id, app_id);
+
+alter table fn_license
+ add constraint fn_license_id primary key (id);
+
+alter table fn_license_contact
+ add constraint fn_license_contact_id primary key (id);
+
+alter table fn_license_history
+ add constraint fn_license_history_id primary key (id);
+
+alter table fn_license_version
+ add constraint fn_license_version_id primary key (id);
+
+create index fn_audit_log_activity_cd on fn_audit_log using btree(activity_cd);
+
+create index fn_audit_log_user_id on fn_audit_log using btree(user_id);
+
+create index fn_menu_function_cd on fn_menu using btree(function_cd);
+
+create index fn_org_access_cd on fn_org using btree(access_cd);
+
+create index fn_role_function_function_cd on fn_role_function using btree (function_cd);
+
+create index fn_role_function_role_id on fn_role_function using btree(role_id);
+
+create index fn_user_address_id on fn_user using btree(address_id);
+
+create index fn_user_alert_method_cd on fn_user using btree (alert_method_cd);
+
+create unique index fn_user_hrid on fn_user using btree (hrid);
+
+create unique index fn_user_login_id on fn_user using btree(login_id);
+
+create index fn_user_org_id on fn_user using btree(org_id);
+
+create index fn_user_role_role_id on fn_user_role using btree(role_id);
+
+create index fn_user_role_user_id on fn_user_role using btree(user_id);
+
+create unique index fn_xmltype_id on fn_xmltype using btree(id);
+
+create index fk_fn_user__ref_178_fn_app_IDX on fn_user_role using btree(app_id);
+
+create index fn_license_app_id on fn_license_app using btree(id);
+
+alter table fn_user_role
+ add constraint fk_fn_user__ref_178_fn_app foreign key (app_id) references fn_app(app_id);
+
+alter table fn_tab
+ add constraint fk_fn_tab_function_cd foreign key (function_cd) references fn_function(function_cd);
+
+alter table fn_tab_selected
+ add constraint fk_fn_tab_selected_tab_cd foreign key (selected_tab_cd) references fn_tab(tab_cd);
+
+alter table fn_tab
+ add constraint fk_fn_tab_set_cd foreign key (tab_set_cd) references fn_lu_tab_set(tab_set_cd);
+
+alter table fn_user
+ add constraint fk_fn_user_ref_110_fn_org foreign key (org_id) references fn_org(org_id);
+
+alter table fn_user
+ add constraint fk_fn_user_ref_123_fn_lu_al foreign key (alert_method_cd) references fn_lu_alert_method(alert_method_cd);
+
+alter table fn_user
+ add constraint fk_fn_user_ref_197_fn_user foreign key (manager_id) references fn_user(user_id);
+
+alter table fn_user
+ add constraint fk_fn_user_ref_198_fn_user foreign key (created_id) references fn_user(user_id);
+
+alter table fn_user
+ add constraint fk_fn_user_ref_199_fn_user foreign key (modified_id) references fn_user(user_id);
+
+alter table fn_user_pseudo_role
+ add constraint fk_pseudo_role_pseudo_role_id foreign key (pseudo_role_id) references fn_role(role_id);
+
+alter table fn_user_pseudo_role
+ add constraint fk_pseudo_role_user_id foreign key (user_id) references fn_user(user_id);
+
+alter table fn_restricted_url
+ add constraint fk_restricted_url_function_cd foreign key (function_cd) references fn_function(function_cd);
+
+alter table fn_license
+ add constraint fn_license_r02 foreign key (quantum_version_id) references fn_license_version(id);
diff --git a/ecd-app-common/db-scripts/ecd-dml-postgres-1707-common.sql b/ecd-app-common/db-scripts/ecd-dml-postgres-1707-common.sql
new file mode 100644
index 0000000..865248d
--- /dev/null
+++ b/ecd-app-common/db-scripts/ecd-dml-postgres-1707-common.sql
@@ -0,0 +1,446 @@
+-- ---------------------------------------------------------------------------------------------------------------
+-- This script populates tables for the ECOMP Controller Dashboard web app.
+-- in the 1707 release with data for all versions.
+-- ---------------------------------------------------------------------------------------------------------------
+
+SET SEARCH_PATH = (schema name);
+
+-- fn_lu_activity
+Insert into fn_lu_activity (ACTIVITY_CD,ACTIVITY) values ('add_role','add_role');
+Insert into fn_lu_activity (ACTIVITY_CD,ACTIVITY) values ('remove_role','remove_role');
+Insert into fn_lu_activity (ACTIVITY_CD,ACTIVITY) values ('add_user_role','add_user_role');
+Insert into fn_lu_activity (ACTIVITY_CD,ACTIVITY) values ('remove_user_role','remove_user_role');
+Insert into fn_lu_activity (ACTIVITY_CD,ACTIVITY) values ('add_role_function','add_role_function');
+Insert into fn_lu_activity (ACTIVITY_CD,ACTIVITY) values ('remove_role_function','remove_role_function');
+Insert into fn_lu_activity (ACTIVITY_CD,ACTIVITY) values ('add_child_role','add_child_role');
+Insert into fn_lu_activity (ACTIVITY_CD,ACTIVITY) values ('remove_child_role','remove_child_role');
+Insert into fn_lu_activity (ACTIVITY_CD,ACTIVITY) values ('login','Login');
+Insert into fn_lu_activity (ACTIVITY_CD,ACTIVITY) values ('logout','Logout');
+
+-- fn_lu_alert_method
+Insert into fn_lu_alert_method (ALERT_METHOD_CD,ALERT_METHOD) values ('PHONE','Phone');
+Insert into fn_lu_alert_method (ALERT_METHOD_CD,ALERT_METHOD) values ('FAX','Fax');
+Insert into fn_lu_alert_method (ALERT_METHOD_CD,ALERT_METHOD) values ('PAGER','Pager');
+Insert into fn_lu_alert_method (ALERT_METHOD_CD,ALERT_METHOD) values ('EMAIL','Email');
+Insert into fn_lu_alert_method (ALERT_METHOD_CD,ALERT_METHOD) values ('SMS','SMS');
+
+-- fn_lu_country
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('YU','Yugoslavia','Yugoslavia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('ZA','South Africa','South Africa',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('ZM','Zambia','Zambia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('ZR','Zaire','Zaire',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('ZW','Zimbabwe','Zimbabwe',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AD','Andorra','Andorra',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AE','United Arab Emirates','United Arab Emirates',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AF','Afghanistan','Afghanistan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AG','Antigua and Barbuda','Antigua and Barbuda',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AI','Anguilla','Anguilla',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AL','Albania','Albania',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AM','Armenia','Armenia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AN','Netherlands Antilles','Netherlands Antilles',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AO','Angola','Angola',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AQ','Antarctica','Antarctica',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AR','Argentina','Argentina',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AS','American Samoa','American Samoa',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AT','Austria','Austria',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AU','Australia','Australia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AW','Aruba','Aruba',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('AZ','Azerbaidjan','Azerbaidjan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BA','Bosnia-Herzegovina','Bosnia-Herzegovina',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BB','Barbados','Barbados',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BD','Bangladesh','Bangladesh',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BE','Belgium','Belgium',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BF','Burkina Faso','Burkina Faso',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BG','Bulgaria','Bulgaria',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BH','Bahrain','Bahrain',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BI','Burundi','Burundi',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BJ','Benin','Benin',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BM','Bermuda','Bermuda',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BN','Brunei Darussalam','Brunei Darussalam',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BO','Bolivia','Bolivia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BR','Brazil','Brazil',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BS','Bahamas','Bahamas',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BT','Bhutan','Bhutan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BV','Bouvet Island','Bouvet Island',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BW','Botswana','Botswana',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BY','Belarus','Belarus',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('BZ','Belize','Belize',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CA','Canada','Canada',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CC','Cocos (Keeling) Islands','Cocos (Keeling) Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CF','Central African Republic','Central African Republic',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CG','Congo','Congo',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CH','Switzerland','Switzerland',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CI','Ivory Coast (Cote D''Ivoire)','Ivory Coast (Cote D''Ivoire)',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CK','Cook Islands','Cook Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CL','Chile','Chile',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CM','Cameroon','Cameroon',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CN','China','China','China');
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CO','Colombia','Colombia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CR','Costa Rica','Costa Rica',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CS','Former Czechoslovakia','Former Czechoslovakia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CU','Cuba','Cuba',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CV','Cape Verde','Cape Verde',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CX','Christmas Island','Christmas Island',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CY','Cyprus','Cyprus',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('CZ','Czech Republic','Czech Republic',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('DE','Germany','Germany',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('DJ','Djibouti','Djibouti',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('DK','Denmark','Denmark',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('DM','Dominica','Dominica',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('DO','Dominican Republic','Dominican Republic',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('DZ','Algeria','Algeria',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('EC','Ecuador','Ecuador',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('EE','Estonia','Estonia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('EG','Egypt','Egypt',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('EH','Western Sahara','Western Sahara',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('ER','Eritrea','Eritrea',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('ES','Spain','Spain',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('ET','Ethiopia','Ethiopia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('FI','Finland','Finland',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('FJ','Fiji','Fiji',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('FK','Falkland Islands','Falkland Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('FM','Micronesia','Micronesia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('FO','Faroe Islands','Faroe Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('FR','France','France',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('FX','France (European Territory)','France (European Territory)',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GA','Gabon','Gabon',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GB','Great Britain','Great Britain',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GD','Grenada','Grenada',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GE','Georgia','Georgia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GF','French Guyana','French Guyana',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GH','Ghana','Ghana',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GI','Gibraltar','Gibraltar',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GL','Greenland','Greenland',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GM','Gambia','Gambia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GN','Guinea','Guinea',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GP','Guadeloupe (French)','Guadeloupe (French)',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GQ','Equatorial Guinea','Equatorial Guinea',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GR','Greece','Greece',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GS','S. Georgia and S. Sandwich Isls.','S. Georgia and S. Sandwich Isls.',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GT','Guatemala','Guatemala',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GU','Guam (USA)','Guam (USA)',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GW','Guinea Bissau','Guinea Bissau',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('GY','Guyana','Guyana',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('HK','Hong Kong','Hong Kong',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('HM','Heard and McDonald Islands','Heard and McDonald Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('HN','Honduras','Honduras',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('HR','Croatia','Croatia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('HT','Haiti','Haiti',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('HU','Hungary','Hungary',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('ID','Indonesia','Indonesia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('IE','Ireland','Ireland',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('IL','Israel','Israel',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('IN','India','India',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('IO','British Indian Ocean Territory','British Indian Ocean Territory',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('IQ','Iraq','Iraq',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('IR','Iran','Iran',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('IS','Iceland','Iceland',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('IT','Italy','Italy',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('JM','Jamaica','Jamaica',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('JO','Jordan','Jordan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('JP','Japan','Japan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KE','Kenya','Kenya',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KG','Kyrgyzstan','Kyrgyzstan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KH','Cambodia','Cambodia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KI','Kiribati','Kiribati',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KM','Comoros','Comoros',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KN','Saint Kitts and Nevis Anguilla','Saint Kitts and Nevis Anguilla',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KP','North Korea','North Korea',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KR','South Korea','South Korea',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KW','Kuwait','Kuwait',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KY','Cayman Islands','Cayman Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('KZ','Kazakhstan','Kazakhstan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LA','Laos','Laos',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LB','Lebanon','Lebanon',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LC','Saint Lucia','Saint Lucia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LI','Liechtenstein','Liechtenstein',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LK','Sri Lanka','Sri Lanka',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LR','Liberia','Liberia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LS','Lesotho','Lesotho',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LT','Lithuania','Lithuania',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LU','Luxembourg','Luxembourg',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LV','Latvia','Latvia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('LY','Libya','Libya',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MA','Morocco','Morocco',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MC','Monaco','Monaco',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MD','Moldavia','Moldavia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MG','Madagascar','Madagascar',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MH','Marshall Islands','Marshall Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MK','Macedonia','Macedonia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('ML','Mali','Mali',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MM','Myanmar','Myanmar',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MN','Mongolia','Mongolia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MO','Macau','Macau',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MP','Northern Mariana Islands','Northern Mariana Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MQ','Martinique (French)','Martinique (French)',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MR','Mauritania','Mauritania',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MS','Montserrat','Montserrat',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MT','Malta','Malta',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MU','Mauritius','Mauritius',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MV','Maldives','Maldives',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MW','Malawi','Malawi',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MX','Mexico','Mexico','Mexico');
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MY','Malaysia','Malaysia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('MZ','Mozambique','Mozambique',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NA','Namibia','Namibia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NC','New Caledonia (French)','New Caledonia (French)',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NE','Niger','Niger',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NF','Norfolk Island','Norfolk Island',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NG','Nigeria','Nigeria',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NI','Nicaragua','Nicaragua',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NL','Netherlands','Netherlands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NO','Norway','Norway',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NP','Nepal','Nepal',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NR','Nauru','Nauru',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NU','Niue','Niue',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('NZ','New Zealand','New Zealand',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('OM','Oman','Oman',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PA','Panama','Panama',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PE','Peru','Peru',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PF','Polynesia (French)','Polynesia (French)',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PG','Papua New Guinea','Papua New Guinea',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PH','Philippines','Philippines',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PK','Pakistan','Pakistan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PL','Poland','Poland',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PM','Saint Pierre and Miquelon','Saint Pierre and Miquelon',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PN','Pitcairn Island','Pitcairn Island',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PR','Puerto Rico','Puerto Rico',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PT','Portugal','Portugal',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PW','Palau','Palau',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('PY','Paraguay','Paraguay',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('QA','Qatar','Qatar',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('RE','Reunion (French)','Reunion (French)',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('RO','Romania','Romania',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('RU','Russian Federation','Russian Federation',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('RW','Rwanda','Rwanda',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SA','Saudi Arabia','Saudi Arabia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SB','Solomon Islands','Solomon Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SC','Seychelles','Seychelles',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SD','Sudan','Sudan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SE','Sweden','Sweden',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SG','Singapore','Singapore',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SH','Saint Helena','Saint Helena',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SI','Slovenia','Slovenia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SJ','Svalbard and Jan Mayen Islands','Svalbard and Jan Mayen Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SK','Slovak Republic','Slovak Republic',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SL','Sierra Leone','Sierra Leone',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SM','San Marino','San Marino',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SN','Senegal','Senegal',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SO','Somalia','Somalia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SR','Suriname','Suriname',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('ST','Saint Tome (Sao Tome) and Principe','Saint Tome (Sao Tome) and Principe',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SU','Former USSR','Former USSR',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SV','El Salvador','El Salvador',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SY','Syria','Syria',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('SZ','Swaziland','Swaziland',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TC','Turks and Caicos Islands','Turks and Caicos Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TD','Chad','Chad',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TF','French Southern Territories','French Southern Territories',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TG','Togo','Togo',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TH','Thailand','Thailand',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TJ','Tadjikistan','Tadjikistan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TK','Tokelau','Tokelau',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TM','Turkmenistan','Turkmenistan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TN','Tunisia','Tunisia',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TO','Tonga','Tonga',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TP','East Timor','East Timor',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TR','Turkey','Turkey',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TT','Trinidad and Tobago','Trinidad and Tobago',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TV','Tuvalu','Tuvalu',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TW','Taiwan','Taiwan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('TZ','Tanzania','Tanzania',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('UA','Ukraine','Ukraine',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('UG','Uganda','Uganda',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('UK','United Kingdom','United Kingdom',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('UM','USA Minor Outlying Islands','USA Minor Outlying Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('US','United States','United States','USA');
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('UY','Uruguay','Uruguay',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('UZ','Uzbekistan','Uzbekistan',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('VA','Vatican City State','Vatican City State',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('VC','Saint Vincent and Grenadines','Saint Vincent and Grenadines',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('VE','Venezuela','Venezuela',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('VG','Virgin Islands (British)','Virgin Islands (British)',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('VI','Virgin Islands (USA)','Virgin Islands (USA)',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('VN','Vietnam','Vietnam',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('VU','Vanuatu','Vanuatu',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('WF','Wallis and Futuna Islands','Wallis and Futuna Islands',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('WS','Samoa','Samoa',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('YE','Yemen','Yemen',null);
+Insert into fn_lu_country (COUNTRY_CD,COUNTRY,FULL_NAME,WEBPHONE_COUNTRY_LABEL) values ('YT','Mayotte','Mayotte',null);
+
+-- fn_lu_menu_set
+Insert into fn_lu_menu_set (MENU_SET_CD,MENU_SET_NAME) values ('APP','Application Menu');
+
+-- fn_lu_priority
+Insert into fn_lu_priority (PRIORITY_ID,PRIORITY,ACTIVE_YN,SORT_ORDER) values (10,'Low','Y',10);
+Insert into fn_lu_priority (PRIORITY_ID,PRIORITY,ACTIVE_YN,SORT_ORDER) values (20,'Normal','Y',20);
+Insert into fn_lu_priority (PRIORITY_ID,PRIORITY,ACTIVE_YN,SORT_ORDER) values (30,'High','Y',30);
+Insert into fn_lu_priority (PRIORITY_ID,PRIORITY,ACTIVE_YN,SORT_ORDER) values (40,'Urgent','Y',40);
+Insert into fn_lu_priority (PRIORITY_ID,PRIORITY,ACTIVE_YN,SORT_ORDER) values (50,'Fatal','Y',50);
+
+-- fn_lu_state
+Insert into fn_lu_state (STATE_CD,STATE) values ('NJ','NJ - New Jersey');
+Insert into fn_lu_state (STATE_CD,STATE) values ('NY','NY - New York');
+Insert into fn_lu_state (STATE_CD,STATE) values ('CA','CA - California');
+Insert into fn_lu_state (STATE_CD,STATE) values ('CO','CO - Colorado');
+Insert into fn_lu_state (STATE_CD,STATE) values ('FL','FL - Florida');
+Insert into fn_lu_state (STATE_CD,STATE) values ('GA','GA - Georgia');
+Insert into fn_lu_state (STATE_CD,STATE) values ('VA','VA - Virginia');
+Insert into fn_lu_state (STATE_CD,STATE) values ('KY','KY - Kentucky');
+Insert into fn_lu_state (STATE_CD,STATE) values ('TX','TX - Texas');
+Insert into fn_lu_state (STATE_CD,STATE) values ('AK','AK - Alaska');
+Insert into fn_lu_state (STATE_CD,STATE) values ('AL','AL - Alabama');
+Insert into fn_lu_state (STATE_CD,STATE) values ('AR','AR - Arkansas');
+Insert into fn_lu_state (STATE_CD,STATE) values ('AZ','AZ - Arizona');
+Insert into fn_lu_state (STATE_CD,STATE) values ('CT','CT - Connecticut');
+Insert into fn_lu_state (STATE_CD,STATE) values ('DC','DC - District Of Columbia');
+Insert into fn_lu_state (STATE_CD,STATE) values ('DE','DE - Delaware');
+Insert into fn_lu_state (STATE_CD,STATE) values ('HI','HI - Hawaii');
+Insert into fn_lu_state (STATE_CD,STATE) values ('ID','ID - Idaho');
+Insert into fn_lu_state (STATE_CD,STATE) values ('IL','IL - Illinois');
+Insert into fn_lu_state (STATE_CD,STATE) values ('IN','IN - Indiana');
+Insert into fn_lu_state (STATE_CD,STATE) values ('IA','IA - Iowa');
+Insert into fn_lu_state (STATE_CD,STATE) values ('KS','KS - Kansas');
+Insert into fn_lu_state (STATE_CD,STATE) values ('LA','LA - Louisiana');
+Insert into fn_lu_state (STATE_CD,STATE) values ('MA','MA - Massachusetts');
+Insert into fn_lu_state (STATE_CD,STATE) values ('MD','MD - Maryland');
+Insert into fn_lu_state (STATE_CD,STATE) values ('ME','ME - Maine');
+Insert into fn_lu_state (STATE_CD,STATE) values ('MI','MI - Michigan');
+Insert into fn_lu_state (STATE_CD,STATE) values ('MN','MN - Minnesota');
+Insert into fn_lu_state (STATE_CD,STATE) values ('MO','MO - Missouri');
+Insert into fn_lu_state (STATE_CD,STATE) values ('MS','MS - Mississippi');
+Insert into fn_lu_state (STATE_CD,STATE) values ('MT','MT - Montana');
+Insert into fn_lu_state (STATE_CD,STATE) values ('NC','NC - North Carolina');
+Insert into fn_lu_state (STATE_CD,STATE) values ('ND','ND - North Dakota');
+Insert into fn_lu_state (STATE_CD,STATE) values ('NE','NE - Nebraska');
+Insert into fn_lu_state (STATE_CD,STATE) values ('NH','NH - New Hampshire');
+Insert into fn_lu_state (STATE_CD,STATE) values ('NM','NM - New Mexico');
+Insert into fn_lu_state (STATE_CD,STATE) values ('NV','NV - Nevada');
+Insert into fn_lu_state (STATE_CD,STATE) values ('OH','OH - Ohio');
+Insert into fn_lu_state (STATE_CD,STATE) values ('OK','OK - Oklahoma');
+Insert into fn_lu_state (STATE_CD,STATE) values ('OR','OR - Oregon');
+Insert into fn_lu_state (STATE_CD,STATE) values ('PA','PA - Pennsylvania');
+Insert into fn_lu_state (STATE_CD,STATE) values ('PR','PR - Puerto Rico');
+Insert into fn_lu_state (STATE_CD,STATE) values ('RI','RI - Rhode Island');
+Insert into fn_lu_state (STATE_CD,STATE) values ('SC','SC - South Carolina');
+Insert into fn_lu_state (STATE_CD,STATE) values ('SD','SD - South Dakota');
+Insert into fn_lu_state (STATE_CD,STATE) values ('TN','TN - Tennessee');
+Insert into fn_lu_state (STATE_CD,STATE) values ('UT','UT - Utah');
+Insert into fn_lu_state (STATE_CD,STATE) values ('VT','VT - Vermont');
+Insert into fn_lu_state (STATE_CD,STATE) values ('WA','WA - Washington');
+Insert into fn_lu_state (STATE_CD,STATE) values ('WV','WV - West Virginia');
+Insert into fn_lu_state (STATE_CD,STATE) values ('WI','WI - Wisconsin');
+Insert into fn_lu_state (STATE_CD,STATE) values ('WY','WY - Wyoming');
+Insert into fn_lu_state (STATE_CD,STATE) values ('VI','VI-Virgin Island');
+
+-- fn_lu_tab_set
+Insert into fn_lu_tab_set (TAB_SET_CD,TAB_SET_NAME) values ('APP','Application Tabs');
+
+-- fn_lu_timezone
+Insert into fn_lu_timezone (TIMEZONE_ID,TIMEZONE_NAME,TIMEZONE_VALUE) values (10,'US/Eastern','US/Eastern');
+Insert into fn_lu_timezone (TIMEZONE_ID,TIMEZONE_NAME,TIMEZONE_VALUE) values (20,'US/Central','US/Central');
+Insert into fn_lu_timezone (TIMEZONE_ID,TIMEZONE_NAME,TIMEZONE_VALUE) values (30,'US/Mountain','US/Mountain');
+Insert into fn_lu_timezone (TIMEZONE_ID,TIMEZONE_NAME,TIMEZONE_VALUE) values (40,'US/Arizona','America/Phoenix');
+Insert into fn_lu_timezone (TIMEZONE_ID,TIMEZONE_NAME,TIMEZONE_VALUE) values (50,'US/Pacific','US/Pacific');
+Insert into fn_lu_timezone (TIMEZONE_ID,TIMEZONE_NAME,TIMEZONE_VALUE) values (60,'US/Alaska','US/Alaska');
+Insert into fn_lu_timezone (TIMEZONE_ID,TIMEZONE_NAME,TIMEZONE_VALUE) values (70,'US/Hawaii','US/Hawaii');
+
+-- fn_function
+Insert into fn_function (FUNCTION_CD,FUNCTION_NAME) values ('login','Login');
+Insert into fn_function (FUNCTION_CD,FUNCTION_NAME) values ('menu_ecd','Home Menu');
+Insert into fn_function (FUNCTION_CD,FUNCTION_NAME) values ('menu_cloudify','Cloudify Menu');
+Insert into fn_function (FUNCTION_CD,FUNCTION_NAME) values ('menu_consul','Consul Menu');
+Insert into fn_function (FUNCTION_CD,FUNCTION_NAME) values ('menu_profile','Profile Menu');
+Insert into fn_function (FUNCTION_CD,FUNCTION_NAME) values ('menu_profile_create','Profile Create');
+Insert into fn_function (FUNCTION_CD,FUNCTION_NAME) values ('menu_profile_import','Profile Import');
+Insert into fn_function (FUNCTION_CD,FUNCTION_NAME) values ('menu_admin','Admin Menu');
+Insert into fn_function (FUNCTION_CD,FUNCTION_NAME) values ('menu_logout','Logout Menu');
+
+-- fn_menu
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (1, 'Root', NULL, 10, NULL, 'menu_ecd', 'N', NULL, NULL, NULL, NULL, 'APP', 'N', NULL);
+INSERT INTO fn_menu
+ (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (30001,'Home', 1, 15,'ecd#', 'menu_ecd', 'Y','N/A','N/A','N/A','N/A','APP','N','icon-building-home');
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (30002,'Components', 1, 20,'#', 'menu_cloudify', 'Y','N/A','N/A','N/A','N/A','APP','N','icon-building-door');
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (30003,'TOSCA Models', 30002, 25,'ecd#/tosca', 'menu_cloudify', 'Y','N/A','N/A','N/A','N/A','APP','N',NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (30004,'Blueprints', 30002, 30,'ecd#/bp', 'menu_cloudify', 'Y','N/A','N/A','N/A','N/A','APP','N',NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (30005,'Deployments', 30002, 35,'ecd#/dep', 'menu_cloudify', 'Y','N/A','N/A','N/A','N/A','APP','N',NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (30006,'Executions', 30002, 40,'ecd#/exe', 'menu_cloudify', 'Y','N/A','N/A','N/A','N/A','APP','N',NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (30007,'System Health', 1, 45,'#', 'menu_consul', 'Y','N/A','N/A','N/A','N/A','APP','N','icon-datanetwork-softwareasaservice');
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (30008,'Service Health', 30007, 50,'ecd#/sh', 'menu_consul', 'Y','N/A','N/A','N/A','N/A','APP','N',NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (30009,'Node Health', 30007, 55,'ecd#/nh', 'menu_consul', 'Y','N/A','N/A','N/A','N/A','APP','N',NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (30010,'Data Centers', 30007, 60,'ecd#/dc', 'menu_consul', 'N','N/A','N/A','N/A','N/A','APP','N',NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (9, 'Users', 1, 90, '#', 'menu_profile', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', 'icon-people-oneperson');
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (930, 'Search', 9, 15, 'ecd#/profile_search', 'menu_admin', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (94, 'Self', 9, 40, 'ecd#/self_profile', 'menu_profile', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (10, 'Admin', 1, 110, '#', 'menu_admin', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', 'icon-controls-settingsconnectedactivity');
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (101, 'Roles', 10, 20, 'ecd#/role_list', 'menu_admin', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (102, 'Role Functions', 10, 30, 'ecd#/role_function_list', 'menu_admin', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (105, 'Cache Admin', 10, 40, 'ecd#/jcs_admin', 'menu_admin', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (108, 'Usage', 10, 80, 'ecd#/usage_list', 'menu_admin', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', NULL);
+INSERT INTO fn_menu (MENU_ID, LABEL, PARENT_ID, SORT_ORDER, ACTION, FUNCTION_CD, ACTIVE_YN, SERVLET, QUERY_STRING, EXTERNAL_URL, TARGET, MENU_SET_CD, SEPARATOR_YN, IMAGE_SRC)
+ VALUES (150022, 'Menus', 10, 60, 'ecd#/admin_menu_edit', 'menu_admin', 'Y', NULL, NULL, NULL, NULL, 'APP', 'N', NULL);
+
+-- fn_restricted_url
+INSERT INTO fn_restricted_url (restricted_url, function_cd) VALUES ('role.htm','menu_admin');
+INSERT INTO fn_restricted_url (restricted_url, function_cd) VALUES ('role_function.htm','menu_admin');
+INSERT INTO fn_restricted_url (restricted_url, function_cd) VALUES ('profile.htm','menu_profile_create');
+
+-- fn_role
+Insert into fn_role (ROLE_ID,ROLE_NAME,ACTIVE_YN,PRIORITY) values (1,'System Administrator','Y',1);
+Insert into fn_role (ROLE_ID,ROLE_NAME,ACTIVE_YN,PRIORITY) values (16,'Standard User','Y',5);
+
+-- fn_role_composite
+Insert into fn_role_composite (PARENT_ROLE_ID,CHILD_ROLE_ID) values (1,16);
+
+-- fn_role_function
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (1,'login');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (1,'menu_ecd');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (1,'menu_cloudify');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (1,'menu_consul');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (1,'menu_profile');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (1,'menu_admin');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (1,'menu_profile_create');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (1,'menu_profile_import');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (1,'menu_logout');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (16,'login');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (16,'menu_ecd');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (16,'menu_cloudify');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (16,'menu_consul');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (16,'menu_profile');
+Insert into fn_role_function (ROLE_ID,FUNCTION_CD) values (16,'menu_logout');
+
+-- fn_user
+-- This row defines a superuser which is accepted by login_extern.htm
+-- The superuser entry is disabled in this checked-in version, ACTIVE = N,
+-- because it is a security hole that should not exist in IST, ETE and PROD.
+Insert into fn_user
+ (USER_ID,ORG_ID,MANAGER_ID,FIRST_NAME,MIDDLE_NAME,LAST_NAME,PHONE,FAX,CELLULAR,EMAIL,ADDRESS_ID,ALERT_METHOD_CD,HRID,ORG_USER_ID,ORG_CODE,LOGIN_ID,LOGIN_PWD,LAST_LOGIN_DATE,ACTIVE_YN,CREATED_ID,CREATED_DATE,MODIFIED_ID,MODIFIED_DATE,IS_INTERNAL_YN,ADDRESS_LINE_1,ADDRESS_LINE_2,CITY,STATE_CD,ZIP_CODE,COUNTRY_CD,LOCATION_CLLI,ORG_MANAGER_USERID,COMPANY,DEPARTMENT_NAME,JOB_TITLE,TIMEZONE,DEPARTMENT,BUSINESS_UNIT,BUSINESS_UNIT_NAME,COST_CENTER,FIN_LOC_CODE,SILO_STATUS)
+ values
+ (1,null,null,'Super',null,'User','908-901-2494',null,null,'email@onap.org',null,null,null,'s12345',null,'su','fusion',to_date('21-AUG-14','%d-%M-%Y'),'Y',null,to_date('15-DEC-05','%d-%M-%Y'),1,to_date('21-AUG-14','%d-%M-%Y'),'N',null,null,null,'NJ',null,'US',null,null,null,null,null,10,null,null,null,null,null,null)
+ ;
+
+-- fn_app
+-- Use appropriate app name (not "Default")
+Insert into fn_app (APP_ID,APP_NAME,APP_IMAGE_URL,APP_DESCRIPTION,APP_NOTES,APP_URL,APP_ALTERNATE_URL,APP_REST_ENDPOINT,ML_APP_NAME,ML_APP_ADMIN_ID,MOTS_ID,APP_PASSWORD,OPEN,ENABLED,THUMBNAIL,APP_USERNAME,UEB_KEY,UEB_SECRET,UEB_TOPIC_NAME) VALUES (1,'EC-DASH-APP','assets/images/tmp/portal1.png','Some Default Description','Some Default Note','http://www.onap.org/1','http://www.onap.org/2',null,'ECPP','?','1','okYTaDrhzibcbGVq5mjkVQ==','N','N',null,'Default',null,null,'ECOMP-PORTAL-INBOX');
+
+-- fn_user_role
+Insert into fn_user_role (USER_ID,ROLE_ID,PRIORITY,APP_ID) values (1,1,null,1);
diff --git a/ecd-app-common/pom.xml b/ecd-app-common/pom.xml
new file mode 100644
index 0000000..fcfcdb8
--- /dev/null
+++ b/ecd-app-common/pom.xml
@@ -0,0 +1,256 @@
+<?xml version="1.0"?>
+<!--
+ =============LICENSE_START=========================================================
+
+ =================================================================================
+ Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.onap.oom.dashboard</groupId>
+ <artifactId>ecd-app-common</artifactId>
+ <version>1707.4.1-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>ONAP Operations Manager Dashboard common</name>
+ <description>OOM Dashboard common Java code</description>
+
+ <properties>
+ <encoding>UTF-8</encoding>
+ <springframework.version>4.2.0.RELEASE</springframework.version>
+ <hibernate.version>4.3.11.Final</hibernate.version>
+ <eelf.version>1.0.0</eelf.version>
+ <epsdk.version>1.1.0</epsdk.version>
+ <nexusproxy>https://nexus.onap.org</nexusproxy>
+ <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
+ <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
+ <skipTests>true</skipTests>
+ </properties>
+
+ <repositories>
+ <repository>
+ <!-- Releases repository has ECOMP release artifacts -->
+ <id>ecomp-releases</id>
+ <name>OpenECOMP - Release Repository</name>
+ <url>${nexusproxy}/${releaseNexusPath}</url>
+ </repository>
+ <repository>
+ <!-- Snapshots repository has ECOMP snapshot artifacts -->
+ <id>ecomp-snapshots</id>
+ <name>OpenECOMP - Snapshot Repository</name>
+ <url>${nexusproxy}/${snapshotNexusPath}</url>
+ </repository>
+ </repositories>
+
+ <!-- disable doclint, a new feature in Java 8, when generating javadoc -->
+ <profiles>
+ <profile>
+ <id>doclint-java8-disable</id>
+ <activation>
+ <jdk>[1.8,)</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <additionalparam>-Xdoclint:none</additionalparam>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <build>
+ <plugins>
+
+ <!-- Compile to Java 1.8 class output format -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+
+ <!-- Put version into jar also -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.6</version>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <archive-version>${project.version}</archive-version>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+
+ <!-- Generate javadoc jar; see profile for Java 8 -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.10.3</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Generate source jar -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>3.0.0</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+ <dependencies>
+ <!-- For using HTTP Basic Auth in uService REST client -->
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.3.5</version>
+ </dependency>
+ <!-- Postgresql driver -->
+ <dependency>
+ <groupId>org.postgresql</groupId>
+ <artifactId>postgresql</artifactId>
+ <version>9.3-1100-jdbc41</version>
+ </dependency>
+ <!-- SDK components -->
+ <dependency>
+ <groupId>org.openecomp.ecompsdkos</groupId>
+ <artifactId>epsdk-core</artifactId>
+ <version>${epsdk.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.elasticsearch</groupId>
+ <artifactId>elasticsearch</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.att.eelf</groupId>
+ <artifactId>eelf-core</artifactId>
+ <version>${eelf.version}</version>
+ </dependency>
+ <!-- Mapper -->
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>2.6.3</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>2.6.3</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>2.6.3</version>
+ </dependency>
+ <dependency>
+ <groupId>com.mchange</groupId>
+ <artifactId>c3p0</artifactId>
+ <version>0.9.5.2</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ </dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ <version>20160212</version>
+ </dependency>
+ <!-- bridge to implement commons-logging using slf4j -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>1.7.12</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ <version>${springframework.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ <version>${springframework.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-tx</artifactId>
+ <version>${springframework.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ <version>${springframework.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ <version>${springframework.version}</version>
+ </dependency>
+ </dependencies>
+
+ <!-- no distributionManagement section; no jars pushed to Maven central -->
+
+</project>
diff --git a/ecd-app-common/src/main/java/org/onap/fusionapp/model/Result.java b/ecd-app-common/src/main/java/org/onap/fusionapp/model/Result.java
new file mode 100644
index 0000000..1f6328d
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/fusionapp/model/Result.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.fusionapp.model;
+
+/**
+ * Trivial model of a String
+ */
+public class Result {
+ private String result;
+
+ /**
+ * @param result
+ * String
+ */
+ public Result(String result) {
+ this.result = result;
+ }
+
+ /**
+ * @return String
+ */
+ public String getResult() {
+ return result;
+ }
+
+ /**
+ * @param result
+ * String
+ */
+ public void setResult(String result) {
+ this.result = result;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/fusionapp/service/AdminAuthExtension.java b/ecd-app-common/src/main/java/org/onap/fusionapp/service/AdminAuthExtension.java
new file mode 100644
index 0000000..8a64ab5
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/fusionapp/service/AdminAuthExtension.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.fusionapp.service;
+
+import org.openecomp.portalsdk.core.domain.User;
+
+//@Service("adminAuthExtension")
+//@Transactional
+/**
+ * Extension supporting action on authorization of user
+ */
+public class AdminAuthExtension {
+
+ /**
+ * @param user
+ * User who was authenticated
+ */
+ public void saveUserExtension(User user) {
+ // app's developer implement their own logic here, like updating app's
+ // related tables
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/fusionapp/util/CustomLoggingFilter.java b/ecd-app-common/src/main/java/org/onap/fusionapp/util/CustomLoggingFilter.java
new file mode 100644
index 0000000..5ae372f
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/fusionapp/util/CustomLoggingFilter.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.fusionapp.util;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.filter.Filter;
+import ch.qos.logback.core.spi.FilterReply;
+
+/**
+ * Custom Filter class bind with logback.xml configuration file to strip out
+ * certain log messages coming out of special packages or classes.
+ *
+ */
+public class CustomLoggingFilter extends Filter<ILoggingEvent> {
+
+ /**
+ * Custom Filter is added to strip out the continuous U-EB logging messages
+ * But make sure we log the ERROR and WARNING Level messages.
+ *
+ * @param event
+ * Logging event
+ */
+ @Override
+ public FilterReply decide(ILoggingEvent event) {
+ try {
+ if ((event.getLevel() != Level.ERROR || event.getLevel() != Level.WARN)
+ && (event.getThreadName().equalsIgnoreCase("UEBConsumerThread"))
+ && (event.getLoggerName().contains("com.att.nsa")
+ || event.getLoggerName().contains("org.apache.http"))) {
+ return FilterReply.DENY;
+ } else {
+ return FilterReply.NEUTRAL;
+ }
+ } catch (Exception e) {
+ return FilterReply.NEUTRAL;
+ }
+ }
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/CloudifyController.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/CloudifyController.java
new file mode 100644
index 0000000..31e888c
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/CloudifyController.java
@@ -0,0 +1,650 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.controller;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.onap.oom.dashboard.model.CloudifyBlueprint;
+import org.onap.oom.dashboard.model.CloudifyBlueprintUpload;
+import org.onap.oom.dashboard.model.CloudifyDeployment;
+import org.onap.oom.dashboard.model.CloudifyDeploymentList;
+import org.onap.oom.dashboard.model.CloudifyDeploymentRequest;
+import org.onap.oom.dashboard.model.CloudifyExecution;
+import org.onap.oom.dashboard.model.CloudifyExecutionList;
+import org.onap.oom.dashboard.model.CloudifyExecutionRequest;
+import org.onap.oom.dashboard.model.ECTransportModel;
+import org.onap.oom.dashboard.model.RestResponseError;
+import org.onap.oom.dashboard.model.RestResponsePage;
+import org.onap.oom.dashboard.rest.IControllerRestClient;
+import org.openecomp.portalsdk.core.domain.User;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.portalsdk.core.web.support.UserUtils;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.client.HttpStatusCodeException;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+/**
+ * Controller for Cloudify features: blueprints, deployments, executions.
+ * Methods serve Ajax requests made by Angular scripts on pages that show
+ * content.
+ */
+@Controller
+@RequestMapping("/")
+public class CloudifyController extends DashboardRestrictedBaseController {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CloudifyController.class);
+
+ /**
+ * Enum for selecting an item type.
+ */
+ public enum CloudifyDataItem {
+ BLUEPRINT, DEPLOYMENT, EXECUTION;
+ }
+
+ private static final String BLUEPRINTS_PATH = "blueprints";
+ private static final String VIEW_BLUEPRINTS_PATH = "viewblueprints";
+ private static final String DEPLOYMENTS_PATH = "deployments";
+ private static final String EXECUTIONS_PATH = "executions";
+
+ /**
+ * Supports sorting blueprints by ID
+ */
+ private static Comparator<CloudifyBlueprint> blueprintComparator = new Comparator<CloudifyBlueprint>() {
+ @Override
+ public int compare(CloudifyBlueprint o1, CloudifyBlueprint o2) {
+ return o1.id.compareTo(o2.id);
+ }
+ };
+
+ /**
+ * Supports sorting deployments by ID
+ */
+ private static Comparator<CloudifyDeployment> deploymentComparator = new Comparator<CloudifyDeployment>() {
+ @Override
+ public int compare(CloudifyDeployment o1, CloudifyDeployment o2) {
+ return o1.id.compareTo(o2.id);
+ }
+ };
+
+ /**
+ * Supports sorting executions by ID
+ */
+ private static Comparator<CloudifyExecution> executionComparator = new Comparator<CloudifyExecution>() {
+ @Override
+ public int compare(CloudifyExecution o1, CloudifyExecution o2) {
+ return o1.id.compareTo(o2.id);
+ }
+ };
+
+ /**
+ * Gets one page of objects and supporting information via the REST client.
+ * On success, returns a PaginatedRestResponse object as String.
+ *
+ * @param option
+ * Specifies which item list type to get
+ * @param pageNum
+ * Page number of results
+ * @param pageSize
+ * Number of items per browser page
+ * @return JSON block as String, see above.
+ * @throws Exception
+ * On any error; e.g., Network failure.
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private String getItemListForPage(long userId, CloudifyDataItem option, int pageNum, int pageSize)
+ throws Exception {
+ IControllerRestClient restClient = getControllerRestClient(userId);
+ List itemList = null;
+ switch (option) {
+ case BLUEPRINT:
+ itemList = restClient.getBlueprints().items;
+ Collections.sort(itemList, blueprintComparator);
+ break;
+ case DEPLOYMENT:
+ itemList = restClient.getDeployments().items;
+ Collections.sort(itemList, deploymentComparator);
+ break;
+ default:
+ throw new Exception("getItemListForPage failed: unimplemented case: " + option.name());
+ }
+
+ // Shrink if needed
+ final int totalItems = itemList.size();
+ final int pageCount = (int) Math.ceil((double) totalItems / pageSize);
+ if (totalItems > pageSize)
+ itemList = getPageOfList(pageNum, pageSize, itemList);
+ RestResponsePage<List> model = new RestResponsePage<>(totalItems, pageCount, itemList);
+ String outboundJson = objectMapper.writeValueAsString(model);
+ return outboundJson;
+ }
+
+ /**
+ * Gets one page of the specified items. This method traps exceptions and
+ * constructs an appropriate JSON block to report errors.
+ *
+ * @param request
+ * Inbound request
+ * @param option
+ * Item type to get
+ * @return JSON with one page of objects; or an error.
+ */
+ protected String getItemListForPageWrapper(HttpServletRequest request, CloudifyDataItem option) {
+ String outboundJson = null;
+ try {
+ User appUser = UserUtils.getUserSession(request);
+ if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
+ throw new Exception("getItemListForPageWrapper: Failed to get application user");
+ int pageNum = getRequestPageNumber(request);
+ int pageSize = getRequestPageSize(request);
+ outboundJson = getItemListForPage(appUser.getId(), option, pageNum, pageSize);
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "getItemListForPageWrapper caught exception", ex);
+ RestResponseError result = null;
+ if (ex instanceof HttpStatusCodeException)
+ result = new RestResponseError(((HttpStatusCodeException) ex).getResponseBodyAsString());
+ else
+ result = new RestResponseError("Failed to get " + option.name(), ex);
+ try {
+ outboundJson = objectMapper.writeValueAsString(result);
+ } catch (JsonProcessingException jpe) {
+ // Should never, ever happen
+ outboundJson = "{ \"error\" : \"" + jpe.toString() + "\"}";
+ }
+ }
+ return outboundJson;
+ }
+
+ /**
+ * Serves one page of blueprints
+ *
+ * @param request
+ * HttpServletRequest
+ * @return List of CloudifyBlueprint objects
+ */
+ @RequestMapping(value = { BLUEPRINTS_PATH }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getBlueprintsByPage(HttpServletRequest request) {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ String json = getItemListForPageWrapper(request, CloudifyDataItem.BLUEPRINT);
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return json;
+ }
+
+ /**
+ * Serves one page of deployments
+ *
+ * @param request
+ * HttpServletRequest
+ * @return List of CloudifyDeployment objects
+ */
+ @RequestMapping(value = { DEPLOYMENTS_PATH }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getDeploymentsByPage(HttpServletRequest request) {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ String json = getItemListForPageWrapper(request, CloudifyDataItem.DEPLOYMENT);
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return json;
+ }
+
+ /**
+ * Gets the specified blueprint metadata.
+ *
+ * @param id
+ * Blueprint ID
+ * @param request
+ * HttpServletRequest
+ * @return Blueprint as JSON; or error.
+ * @throws Exception
+ * on serialization error
+ *
+ */
+ @RequestMapping(value = { BLUEPRINTS_PATH + "/{id}" }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getBlueprintById(@PathVariable("id") String id, HttpServletRequest request) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ result = restClient.getBlueprint(id);
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("getBlueprintById failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Gets the specified blueprint content for viewing.
+ *
+ * @param id
+ * Blueprint ID
+ * @param request
+ * HttpServletRequest
+ * @return Blueprint as YAML; or error.
+ * @throws Exception
+ * on serialization error
+ *
+ */
+ @RequestMapping(value = {
+ VIEW_BLUEPRINTS_PATH + "/{id}" }, method = RequestMethod.GET, produces = "application/yaml")
+ @ResponseBody
+ public String viewBlueprintContentById(@PathVariable("id") String id, HttpServletRequest request) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ result = restClient.viewBlueprint(id);
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("getBlueprintContentById failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Processes request to upload a blueprint from a remote server.
+ *
+ * @param request
+ * HttpServletRequest
+ * @param blueprint
+ * Cloudify blueprint
+ * @return Blueprint as uploaded; or error.
+ * @throws Exception
+ * on serialization error
+ */
+ @RequestMapping(value = { BLUEPRINTS_PATH }, method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public String uploadBlueprint(HttpServletRequest request, @RequestBody CloudifyBlueprintUpload blueprint)
+ throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ result = restClient.uploadBlueprint(blueprint);
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("uploadBlueprint failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Deletes the specified blueprint.
+ *
+ * @param id
+ * Blueprint ID
+ * @param request
+ * HttpServletRequest
+ * @param response
+ * HttpServletResponse
+ * @return No content on success; error on failure.
+ * @throws Exception
+ * On serialization failure
+ */
+ @RequestMapping(value = { BLUEPRINTS_PATH + "/{id}" }, method = RequestMethod.DELETE, produces = "application/json")
+ @ResponseBody
+ public String deleteBlueprint(@PathVariable("id") String id, HttpServletRequest request,
+ HttpServletResponse response) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ int code = restClient.deleteBlueprint(id);
+ response.setStatus(code);
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("deleteBlueprint failed on ID " + id, t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ if (result == null)
+ return null;
+ else
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Gets the specified deployment.
+ *
+ * @param id
+ * Deployment ID
+ * @param request
+ * HttpServletRequest
+ * @return Deployment for the specified ID; error on failure.
+ * @throws Exception
+ * On serialization failure
+ *
+ */
+ @RequestMapping(value = { DEPLOYMENTS_PATH + "/{id}" }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getDeploymentById(@PathVariable("id") String id, HttpServletRequest request) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ result = restClient.getDeployment(id);
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("getDeploymentById failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Processes request to create a deployment based on a blueprint.
+ *
+ * @param request
+ * HttpServletRequest
+ * @param deployment
+ * Deployment to upload
+ * @return Body of deployment; error on failure
+ * @throws Exception
+ * On serialization failure
+ */
+ @RequestMapping(value = { DEPLOYMENTS_PATH }, method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public String createDeployment(HttpServletRequest request, @RequestBody CloudifyDeploymentRequest deployment)
+ throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ result = restClient.createDeployment(deployment);
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("createDeployment failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Deletes the specified deployment.
+ *
+ * @param id
+ * Deployment ID
+ * @param ignoreLiveNodes
+ * Boolean indicator whether to force a delete in case of live
+ * nodes
+ * @param request
+ * HttpServletRequest
+ * @param response
+ * HttpServletResponse
+ * @return Passes thru HTTP status code from remote endpoint; no body on
+ * success
+ * @throws Exception
+ * on serialization failure
+ */
+ @RequestMapping(value = {
+ DEPLOYMENTS_PATH + "/{id}" }, method = RequestMethod.DELETE, produces = "application/json")
+ @ResponseBody
+ public String deleteDeployment(@PathVariable("id") String id,
+ @RequestParam(value = "ignore_live_nodes", required = false) Boolean ignoreLiveNodes,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ int code = restClient.deleteDeployment(id, ignoreLiveNodes == null ? false : ignoreLiveNodes);
+ response.setStatus(code);
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("deleteDeployment failed on ID " + id, t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ if (result == null)
+ return null;
+ else
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Gets and serves one page of executions:
+ * <OL>
+ * <LI>Gets all deployments; OR uses the specified deployment ID if the
+ * query parameter is present
+ * <LI>Gets executions for each deployment ID
+ * <LI>Sorts by execution ID
+ * <LI>Reduces the list to the page size (if needed)
+ * <LI>If the optional request parameter "status" is present, reduces the
+ * list to the executions with that status.
+ * </OL>
+ *
+ * @param request
+ * HttpServletRequest
+ * @param deployment_id
+ * Optional request parameter; if found, only executions for that
+ * deployment ID are returned.
+ * @param status
+ * Optional request parameter; if found, only executions with
+ * that status are returned.
+ * @return List of CloudifyExecution objects
+ * @throws Exception
+ * on serialization failure
+ */
+ @SuppressWarnings("unchecked")
+ @RequestMapping(value = { EXECUTIONS_PATH }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getExecutionsByPage(HttpServletRequest request,
+ @RequestParam(value = "deployment_id", required = false) String deployment_id,
+ @RequestParam(value = "status", required = false) String status) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ List<CloudifyExecution> itemList = new ArrayList<CloudifyExecution>();
+ IControllerRestClient restClient = getControllerRestClient(request);
+ List<String> depIds = new ArrayList<>();
+ if (deployment_id == null) {
+ CloudifyDeploymentList depList = restClient.getDeployments();
+ for (CloudifyDeployment cd : depList.items)
+ depIds.add(cd.id);
+ } else {
+ depIds.add(deployment_id);
+ }
+ for (String depId : depIds) {
+ CloudifyExecutionList exeList = restClient.getExecutions(depId);
+ itemList.addAll(exeList.items);
+ }
+ // Filter down to specified status as needed
+ if (status != null) {
+ Iterator<CloudifyExecution> exeIter = itemList.iterator();
+ while (exeIter.hasNext()) {
+ CloudifyExecution ce = exeIter.next();
+ if (!status.equals(ce.status))
+ exeIter.remove();
+ }
+ }
+ Collections.sort(itemList, executionComparator);
+
+ // Paginate
+ final int pageNum = getRequestPageNumber(request);
+ final int pageSize = getRequestPageSize(request);
+ final int totalItems = itemList.size();
+ final int pageCount = (int) Math.ceil((double) totalItems / pageSize);
+ // Shrink if needed
+ if (totalItems > pageSize)
+ itemList = getPageOfList(pageNum, pageSize, itemList);
+ result = new RestResponsePage<>(totalItems, pageCount, itemList);
+ } catch (Throwable t) {
+ result = new RestResponseError("getExecutionsByPage failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Gets the specified execution for one deployment.
+ *
+ * It's not clear why the deployment ID is needed.
+ *
+ * @param execution_id
+ * Execution ID (path variable)
+ * @param deployment_id
+ * Deployment ID (query parameter)
+ * @param request
+ * HttpServletRequest
+ * @return CloudifyExecutionList
+ * @throws Exception
+ * on serialization failure
+ */
+ @RequestMapping(value = { EXECUTIONS_PATH + "/{id}" }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getExecutionByIdAndDeploymentId(@PathVariable("id") String execution_id,
+ @RequestParam("deployment_id") String deployment_id, HttpServletRequest request) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ result = restClient.getExecutions(deployment_id);
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("getExecutionByIdAndDeploymentId failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Processes request to create an execution based on a deployment.
+ *
+ * @param request
+ * HttpServletRequest
+ * @param execution
+ * Execution model
+ * @return Information about the execution
+ * @throws Exception
+ * on serialization failure
+ */
+ @RequestMapping(value = { EXECUTIONS_PATH }, method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public String startExecution(HttpServletRequest request, @RequestBody CloudifyExecutionRequest execution)
+ throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ result = restClient.startExecution(execution);
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("startExecution failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Cancels an execution.
+ *
+ * @param id
+ * Execution ID
+ * @param deploymentId
+ * Deployment ID (not clear why this is needed)
+ * @param action
+ * Action to perform (not clear why this is needed)
+ * @param request
+ * HttpServletRequest
+ * @param response
+ * HttpServletRequest
+ * @return Passes thru HTTP status code from remote endpoint; no body on
+ * success
+ * @throws Exception
+ * on serialization failure
+ */
+ @RequestMapping(value = { EXECUTIONS_PATH + "/{id}" }, method = RequestMethod.DELETE, produces = "application/json")
+ @ResponseBody
+ public String cancelExecution(@PathVariable("id") String id,
+ @RequestParam(value = "deployment_id") String deploymentId, @RequestParam(value = "action") String action,
+ HttpServletRequest request, HttpServletResponse response) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ int code = restClient.cancelExecution(id, deploymentId, action);
+ response.setStatus(code);
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("cancelExecution failed on ID " + id, t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ if (result == null)
+ return null;
+ else
+ return objectMapper.writeValueAsString(result);
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/ConsulController.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/ConsulController.java
new file mode 100644
index 0000000..06e80e9
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/ConsulController.java
@@ -0,0 +1,455 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.controller;
+
+import java.net.URI;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.oom.dashboard.model.ConsulHealthServiceRegistration;
+import org.onap.oom.dashboard.model.ConsulNodeInfo;
+import org.onap.oom.dashboard.model.ConsulServiceHealth;
+import org.onap.oom.dashboard.model.ConsulServiceInfo;
+import org.onap.oom.dashboard.model.ECTransportModel;
+import org.onap.oom.dashboard.model.RestResponseError;
+import org.onap.oom.dashboard.model.RestResponsePage;
+import org.onap.oom.dashboard.model.RestResponseSuccess;
+import org.onap.oom.dashboard.rest.IControllerRestClient;
+import org.openecomp.portalsdk.core.domain.User;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.portalsdk.core.web.support.UserUtils;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.client.HttpStatusCodeException;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+/**
+ * Controller for Consul features: health checks of services, nodes, data
+ * centers. Methods serve Ajax requests made by Angular scripts on pages that
+ * show content.
+ */
+@Controller
+@RequestMapping("/healthservices")
+public class ConsulController extends DashboardRestrictedBaseController {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ConsulController.class);
+
+ /**
+ * Enum for selecting an item type.
+ */
+ public enum ConsulDataItem {
+ SERVICE_INFO, SERVICE_HEALTH, NODES, DATACENTERS;
+ }
+
+ private static final String NODES_PATH = "/nodes";
+ private static final String SERVICES_PATH = "/services";
+
+ /**
+ * Supports sorting results by node name
+ */
+ private static Comparator<ConsulNodeInfo> nodeHealthComparator = new Comparator<ConsulNodeInfo>() {
+ @Override
+ public int compare(ConsulNodeInfo o1, ConsulNodeInfo o2) {
+ return o1.node.compareTo(o2.node);
+ }
+ };
+
+ /**
+ * Supports sorting results by service name
+ */
+ private static Comparator<ConsulServiceHealth> serviceHealthComparator = new Comparator<ConsulServiceHealth>() {
+ @Override
+ public int compare(ConsulServiceHealth o1, ConsulServiceHealth o2) {
+ return o1.serviceName.compareTo(o2.serviceName);
+ }
+ };
+
+ /**
+ * Supports sorting results by service name
+ */
+ private static Comparator<ConsulServiceInfo> serviceInfoComparator = new Comparator<ConsulServiceInfo>() {
+ @Override
+ public int compare(ConsulServiceInfo o1, ConsulServiceInfo o2) {
+ return o1.name.compareTo(o2.name);
+ }
+ };
+
+ /**
+ * Gets one page of objects and supporting information via the REST client.
+ * On success, returns a page of objects as String.
+ *
+ * @param option
+ * Specifies which item type to get
+ * @param pageNum
+ * Page number of results
+ * @param pageSize
+ * Number of items per browser page
+ * @return JSON block as String, see above.
+ * @throws Exception
+ * On any error; e.g., Network failure.
+ */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private String getItemListForPage(long userId, ConsulDataItem option, int pageNum, int pageSize) throws Exception {
+ IControllerRestClient restClient = getControllerRestClient(userId);
+ List itemList = null;
+ switch (option) {
+ case NODES:
+ itemList = restClient.getNodes();
+ Collections.sort(itemList, nodeHealthComparator);
+ break;
+ case DATACENTERS:
+ itemList = restClient.getDatacenters();
+ break;
+ default:
+ throw new Exception("getItemListForPage failed: unimplemented case: " + option.name());
+ }
+
+ // Shrink if needed
+ if (itemList.size() > pageSize)
+ itemList = getPageOfList(pageNum, pageSize, itemList);
+ int pageCount = (int) Math.ceil((double) itemList.size() / pageSize);
+ RestResponsePage<List> model = new RestResponsePage<>(itemList.size(), pageCount, itemList);
+ String outboundJson = objectMapper.writeValueAsString(model);
+ return outboundJson;
+ }
+
+ /**
+ * Gets one page of the specified items. This method traps exceptions and
+ * constructs an appropriate JSON block to report errors.
+ *
+ * @param request
+ * Inbound request
+ * @param option
+ * Item type to get
+ * @return JSON with one page of objects; or an error.
+ */
+ protected String getItemListForPageWrapper(HttpServletRequest request, ConsulDataItem option) {
+ String outboundJson = null;
+ try {
+ User appUser = UserUtils.getUserSession(request);
+ if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
+ throw new Exception("getItemListForPageWrapper: Failed to get application user");
+ int pageNum = getRequestPageNumber(request);
+ int pageSize = getRequestPageSize(request);
+ outboundJson = getItemListForPage(appUser.getId(), option, pageNum, pageSize);
+ } catch (Exception ex) {
+ // Remote service failed; build descriptive error message
+ logger.error(EELFLoggerDelegate.errorLogger, "getItemListForPageWrapper caught exception", ex);
+ RestResponseError result = new RestResponseError("Failed to get " + option.name(), ex);
+ try {
+ outboundJson = objectMapper.writeValueAsString(result);
+ } catch (JsonProcessingException jpe) {
+ // Should never, ever happen
+ outboundJson = "{ \"error\" : \"" + jpe.toString() + "\"}";
+ }
+ }
+ return outboundJson;
+ }
+
+ /**
+ * Serves all service details.
+ *
+ * @param request
+ * HttpServletRequest
+ * @return List of ConsulServiceInfo objects, as JSON
+ * @throws Exception
+ * if serialization fails
+ */
+ @RequestMapping(value = { SERVICES_PATH }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getServices(HttpServletRequest request) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ Object result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ List<ConsulServiceInfo> itemList = restClient.getServices();
+ Collections.sort(itemList, serviceInfoComparator);
+ result = itemList;
+ } catch (Throwable t) {
+ result = new RestResponseError("getServices failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Serves service health details - not paginated.
+ *
+ * @param request
+ * HttpServletRequest
+ * @param serviceId
+ * Service ID
+ * @return List of ConsulServiceHealth objects as JSON
+ * @throws Exception
+ * if serialization fails
+ */
+ @RequestMapping(value = {
+ SERVICES_PATH + "/{serviceId}" }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getServiceHealthDetails(HttpServletRequest request, @PathVariable String serviceId) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ Object result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ result = restClient.getServiceHealth(serviceId);
+ } catch (Throwable t) {
+ result = new RestResponseError("getServiceHealthDetails failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Serves service health historical data - not paginated.
+ *
+ * @param request
+ * HttpServletRequest
+ * @param serviceName
+ * Service name as path parameter
+ * @param start
+ * Earliest date-time as an ISO 8061 value, such as
+ * 2007-12-03T10:15:30+01:00
+ * @param end
+ * Latest date-time as an ISO 8061 value, such as
+ * 2007-12-03T10:15:30+01:00
+ * @return List of ConsulServiceHealth objects as JSON
+ * @throws Exception
+ * if serialization fails
+ */
+ @RequestMapping(value = { "/svchist/{serviceName}" }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getServiceHealthHistory(HttpServletRequest request, //
+ @PathVariable String serviceName, //
+ @RequestParam String start, //
+ @RequestParam String end) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ Object result = null;
+ try {
+ Instant startDateTime = Instant.parse(start);
+ Instant endDateTime = Instant.parse(end);
+ IControllerRestClient restClient = getControllerRestClient(request);
+ result = restClient.getServiceHealthHistory(serviceName, startDateTime, endDateTime);
+ } catch (HttpStatusCodeException e) {
+ // Rare, but can happen
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ // Work around the hack to report no-match.
+ result = new RestResponseError("getServiceHealthHistory failed: " + t.getMessage());
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Serves one page of service health information by getting all service
+ * names, then iterating over them to get the health of each service.
+ *
+ * ECOMP-C does NOT provide an API to get the health of all services in one
+ * request.
+ *
+ * @param request
+ * HttpServletRequest
+ * @return List of ConsulServiceHealth objects, as JSON
+ * @throws Exception
+ * on serialization exception
+ */
+ @SuppressWarnings("unchecked")
+ @RequestMapping(value = { "/serviceshealth" }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getServicesHealth(HttpServletRequest request) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ List<ConsulServiceHealth> itemList = new ArrayList<>();
+ IControllerRestClient restClient = getControllerRestClient(request);
+ List<ConsulServiceInfo> svcInfoList = restClient.getServices();
+ for (ConsulServiceInfo csi : svcInfoList) {
+ List<ConsulServiceHealth> csh = restClient.getServiceHealth(csi.name);
+ itemList.addAll(csh);
+ }
+ Collections.sort(itemList, serviceHealthComparator);
+ // Paginate
+ final int pageNum = getRequestPageNumber(request);
+ final int pageSize = getRequestPageSize(request);
+ final int totalItems = itemList.size();
+ final int pageCount = (int) Math.ceil((double) totalItems / pageSize);
+ // Shrink if needed
+ if (totalItems > pageSize)
+ itemList = getPageOfList(pageNum, pageSize, itemList);
+ result = new RestResponsePage<>(totalItems, pageCount, itemList);
+ } catch (Throwable t) {
+ result = new RestResponseError("getServicesHealth failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Serves one page of node information.
+ *
+ * @param request
+ * HttpServletRequest
+ * @return List of ConsulNodeInfo objects, as JSON
+ */
+ @RequestMapping(value = { NODES_PATH }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getNodesInfo(HttpServletRequest request) {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ String json = getItemListForPageWrapper(request, ConsulDataItem.NODES);
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return json;
+ }
+
+ /**
+ * Serves node services health details - not paginated.
+ *
+ * @param request
+ * HttpServletRequest
+ * @param nodeName
+ * Node name
+ * @return List of ConsulServiceHealth objects as JSON
+ * @throws Exception
+ * if serialization fails
+ */
+ @RequestMapping(value = { NODES_PATH + "/{nodeName}" }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getNodeServicesHealth(HttpServletRequest request, @PathVariable String nodeName) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ Object result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ result = restClient.getNodeServicesHealth(nodeName);
+ } catch (Throwable t) {
+ result = new RestResponseError("getNodeServicesHealth failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Serves one page of datacenters health.
+ *
+ * @param request
+ * HttpServletRequest
+ * @return List of ConsulHealthStatus objects
+ */
+ @RequestMapping(value = { "/datacenters" }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getDatacentersHealth(HttpServletRequest request) {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ String json = getItemListForPageWrapper(request, ConsulDataItem.DATACENTERS);
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return json;
+ }
+
+ /**
+ * Processes request to register a service for health checks.
+ *
+ * @param request
+ * HttpServletRequest
+ * @param registration
+ * Consul service registration
+ * @return URI of the newly registered resource
+ * @throws Exception
+ * on serialization error
+ */
+ @RequestMapping(value = { "/register" }, method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public String registerService(HttpServletRequest request, @RequestBody ConsulHealthServiceRegistration registration)
+ throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ URI uri = restClient.registerService(registration);
+ result = new RestResponseSuccess(uri.toString());
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("registerService failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+
+ /**
+ * Processes request to deregister a service for health checks.
+ *
+ * @param request
+ * HttpServletRequest
+ * @param serviceName
+ * Consul service name to deregister
+ * @return Success or error indicator
+ * @throws Exception
+ * on serialization error
+ */
+ @RequestMapping(value = { "/deregister" + "/{serviceName}" }, method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public String deregisterService(HttpServletRequest request,
+ @PathVariable String serviceName) throws Exception {
+ MDC.put(SystemProperties.AUDITLOG_BEGIN_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ ECTransportModel result = null;
+ try {
+ IControllerRestClient restClient = getControllerRestClient(request);
+ int code = restClient.deregisterService(serviceName);
+ result = new RestResponseSuccess("Deregistration yielded code " + Integer.toString(code));
+ } catch (HttpStatusCodeException e) {
+ result = new RestResponseError(e.getResponseBodyAsString());
+ } catch (Throwable t) {
+ result = new RestResponseError("deregisterService failed", t);
+ }
+ MDC.put(SystemProperties.AUDITLOG_END_TIMESTAMP, logDateFormat.format(new Date()));
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ return objectMapper.writeValueAsString(result);
+ }
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/DashboardHomeController.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/DashboardHomeController.java
new file mode 100644
index 0000000..997e5dd
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/DashboardHomeController.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.controller;
+
+import java.util.ArrayList;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.oom.dashboard.domain.ControllerEndpoint;
+import org.onap.oom.dashboard.model.ControllerEndpointCredentials;
+import org.onap.oom.dashboard.model.ControllerEndpointTransport;
+import org.onap.oom.dashboard.model.RestResponseError;
+import org.onap.oom.dashboard.model.RestResponseSuccess;
+import org.onap.oom.dashboard.service.ControllerEndpointService;
+import org.openecomp.portalsdk.core.domain.User;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.web.support.UserUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * This controller maps requests for the application's landing page, which is
+ * an Angular single-page application.
+ */
+@Controller
+@RequestMapping("/")
+public class DashboardHomeController extends DashboardRestrictedBaseController {
+
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(DashboardHomeController.class);
+
+ @Autowired
+ private ControllerEndpointService controllerEndpointService;
+
+ /**
+ * For general use in these methods
+ */
+ private final ObjectMapper mapper;
+
+ private static final String CONTROLLERS_PATH = "controllers";
+
+ /**
+ * Never forget that Spring autowires fields AFTER the constructor is
+ * called.
+ */
+ public DashboardHomeController() {
+ mapper = new ObjectMapper();
+ // Do not serialize null values
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ }
+
+ /**
+ * @return View name key, which is resolved to a file using an Apache tiles
+ * "definitions.xml" file.
+ */
+ @RequestMapping(value = { "/ecd" }, method = RequestMethod.GET)
+ public ModelAndView dbcDefaultController() {
+ // a model is only useful for JSP; this app is angular.
+ return new ModelAndView("ecd_home_tdkey");
+ }
+
+ /**
+ * Gets the available controller endpoints.
+ *
+ * @param request
+ * HttpServletRequest
+ * @return List of ControllerEndpointTransport objects, or an error on
+ * failure
+ * @throws Exception
+ * if application user is not found
+ */
+ @RequestMapping(value = { CONTROLLERS_PATH }, method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public String getControllers(HttpServletRequest request) {
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ String outboundJson = null;
+ // Static data
+ ControllerEndpointCredentials[] configured = getControllerEndpoints();
+ try {
+ User appUser = UserUtils.getUserSession(request);
+ if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
+ throw new Exception("getControllers: Failed to get application user");
+ ControllerEndpointCredentials selectedInDb = getOrSetControllerEndpointSelection(appUser.getId());
+ // Built result from properties
+ ArrayList<ControllerEndpointTransport> list = new ArrayList<>();
+ for (ControllerEndpointCredentials ctrl : configured) {
+ // Check if this is the selected endpoint in DB
+ boolean selected = (selectedInDb != null && selectedInDb.getUrl() != null
+ && selectedInDb.getUrl().equals(ctrl.getUrl()));
+ // Result has no privileged information
+ ControllerEndpointTransport transport = new ControllerEndpointTransport(selected, ctrl.getName(),
+ ctrl.getUrl());
+ list.add(transport);
+ }
+ outboundJson = mapper.writeValueAsString(list);
+ } catch (Exception ex) {
+ RestResponseError response = new RestResponseError("Failed to get controller endpoint list", ex);
+ outboundJson = response.toJson();
+ }
+ return outboundJson;
+ }
+
+ /**
+ * Sets the controller endpoint selection for the user.
+ *
+ * @param request
+ * HttpServletRequest
+ * @param endpoint
+ * Body with endpoint details
+ * @return Result indicating success or failure
+ * @throws Exception
+ * if application user is not found
+ */
+ @RequestMapping(value = { CONTROLLERS_PATH }, method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public String setControllerSelection(HttpServletRequest request, @RequestBody ControllerEndpointTransport endpoint)
+ throws Exception {
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, APP_NAME);
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ String outboundJson = null;
+ User appUser = UserUtils.getUserSession(request);
+ if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
+ throw new Exception("setControllerSelection: Failed to get application user");
+ ControllerEndpoint dbEntry = new ControllerEndpoint(appUser.getId(), endpoint.getName(), endpoint.getUrl());
+ controllerEndpointService.updateControllerEndpointSelection(dbEntry);
+ RestResponseSuccess success = new RestResponseSuccess("Updated selection to " + endpoint.getName());
+ outboundJson = mapper.writeValueAsString(success);
+ return outboundJson;
+ }
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/DashboardRestrictedBaseController.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/DashboardRestrictedBaseController.java
new file mode 100644
index 0000000..c921608
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/DashboardRestrictedBaseController.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.controller;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.oom.dashboard.domain.ControllerEndpoint;
+import org.onap.oom.dashboard.model.ControllerEndpointCredentials;
+import org.onap.oom.dashboard.rest.ControllerRestClientImpl;
+import org.onap.oom.dashboard.rest.ControllerRestClientMockImpl;
+import org.onap.oom.dashboard.rest.IControllerRestClient;
+import org.onap.oom.dashboard.service.ControllerEndpointService;
+import org.onap.oom.dashboard.util.DashboardProperties;
+import org.openecomp.portalsdk.core.controller.RestrictedBaseController;
+import org.openecomp.portalsdk.core.domain.User;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.web.support.UserUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * This base class provides utility methods to child controllers.
+ */
+public class DashboardRestrictedBaseController extends RestrictedBaseController {
+
+ /**
+ * Logger that conforms with ECOMP guidelines
+ */
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(DashboardRestrictedBaseController.class);
+
+ /**
+ * Application name
+ */
+ protected static final String APP_NAME = "ecd-app";
+
+ /**
+ * EELF-approved format
+ */
+ protected static final DateFormat logDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+
+ /**
+ * Query parameter for desired page number
+ */
+ protected static final String PAGE_NUM_QUERY_PARAM = "pageNum";
+
+ /**
+ * Query parameter for desired items per page
+ */
+ protected static final String PAGE_SIZE_QUERY_PARAM = "viewPerPage";
+
+ /**
+ * For general use in these methods and subclasses
+ */
+ protected final ObjectMapper objectMapper = new ObjectMapper();
+
+ /**
+ * Application properties - NOT available to constructor.
+ */
+ @Autowired
+ private DashboardProperties appProperties;
+
+ /**
+ * For getting selected controller
+ */
+ @Autowired
+ private ControllerEndpointService controllerEndpointService;
+
+ /**
+ * Hello Spring, here's your no-arg constructor.
+ */
+ public DashboardRestrictedBaseController() {
+ // Do not serialize null values
+ objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ }
+
+ /**
+ * Access method for subclasses.
+ *
+ * @return DbcappProperties object that was autowired by Spring.
+ */
+ protected DashboardProperties getAppProperties() {
+ return appProperties;
+ }
+
+ /**
+ * Gets the requested page number from a query parameter in the
+ * HttpServletRequest. Defaults to 1, which is useful to allow manual
+ * testing of endpoints without supplying those pesky parameters.
+ *
+ * @param request
+ * HttpServletRequest
+ * @return Value of query parameter {@link #PAGE_NUM_QUERY_PARAM}; 1 if not
+ * found.
+ */
+ protected int getRequestPageNumber(HttpServletRequest request) {
+ int pageNum = 1;
+ String param = request.getParameter(PAGE_NUM_QUERY_PARAM);
+ if (param != null)
+ pageNum = Integer.parseInt(param);
+ return pageNum;
+ }
+
+ /**
+ * Gets the requested page size from a query parameter in the
+ * HttpServletRequest. Defaults to 50, which is useful to allow manual
+ * testing of endpoints without supplying those pesky parameters.
+ *
+ * @param request
+ * HttpServletRequest
+ * @return Value of query parameter {@link #PAGE_SIZE_QUERY_PARAM}; 50 if
+ * not found.
+ */
+ protected int getRequestPageSize(HttpServletRequest request) {
+ int pageSize = 50;
+ String param = request.getParameter(PAGE_SIZE_QUERY_PARAM);
+ if (param != null)
+ pageSize = Integer.parseInt(param);
+ return pageSize;
+ }
+
+ /**
+ * Gets the items for the specified page from the specified list.
+ *
+ * @param pageNum
+ * Page number requested by user, indexed from 1
+ * @param pageSize
+ * Number of items per page
+ * @param itemList
+ * List of items to adjust
+ * @return List of items; empty list if from==to
+ */
+ @SuppressWarnings("rawtypes")
+ protected static List getPageOfList(final int pageNum, final int pageSize, final List itemList) {
+ int firstIndexOnThisPage = pageSize * (pageNum - 1);
+ int firstIndexOnNextPage = pageSize * pageNum;
+ int fromIndex = firstIndexOnThisPage < itemList.size() ? firstIndexOnThisPage : itemList.size();
+ int toIndex = firstIndexOnNextPage < itemList.size() ? firstIndexOnNextPage : itemList.size();
+ return itemList.subList(fromIndex, toIndex);
+ }
+
+ /**
+ * Gets all configured controllers from properties.
+ *
+ * @return Array of ControllerEndpointRestricted objects
+ * @throws IllegalStateException
+ * if a required property is not found
+ */
+ protected ControllerEndpointCredentials[] getControllerEndpoints() {
+ final String[] controllerKeys = appProperties.getCsvListProperty(DashboardProperties.CONTROLLER_KEY_LIST);
+ ControllerEndpointCredentials[] controllers = new ControllerEndpointCredentials[controllerKeys.length];
+ for (int i = 0; i < controllerKeys.length; ++i) {
+ String key = controllerKeys[i];
+ final String name = appProperties.getControllerProperty(key, DashboardProperties.CONTROLLER_SUBKEY_NAME);
+ final String url = appProperties.getControllerProperty(key, DashboardProperties.CONTROLLER_SUBKEY_URL);
+ final String user = appProperties.getControllerProperty(key,
+ DashboardProperties.CONTROLLER_SUBKEY_USERNAME);
+ final String pass = appProperties.getControllerProperty(key,
+ DashboardProperties.CONTROLLER_SUBKEY_PASSWORD);
+ final boolean encr = new Boolean(
+ appProperties.getControllerProperty(key, DashboardProperties.CONTROLLER_SUBKEY_ENCRYPTED));
+ logger.debug(EELFLoggerDelegate.debugLogger, "getConfiguredControllers: key {} yields url {}", key, url);
+ controllers[i] = new ControllerEndpointCredentials(false, name, url, user, pass, encr);
+ }
+ return controllers;
+ }
+
+ /**
+ * Gets the controller endpoint for the specified user ID. Chooses the first
+ * one from properties if the user has not selected one previously.
+ *
+ * @param userId
+ * Database User ID
+ * @return ControllerEndpointCredentials for the specified user
+ */
+ protected ControllerEndpointCredentials getOrSetControllerEndpointSelection(long userId) {
+ // Always need the complete list from properties
+ ControllerEndpointCredentials[] configured = getControllerEndpoints();
+ // See if the database has an entry for this user
+ ControllerEndpoint dbEntry = controllerEndpointService.getControllerEndpointSelection(userId);
+ // If no row found DAO returns an object with null entries.
+ if (dbEntry == null || dbEntry.getName() == null) {
+ // Arbitrarily choose the first one
+ ControllerEndpointCredentials first = configured[0];
+ dbEntry = new ControllerEndpoint(userId, first.getName(), first.getUrl());
+ controllerEndpointService.updateControllerEndpointSelection(dbEntry);
+ }
+ // Fetch complete details for the selected item
+ ControllerEndpointCredentials selected = null;
+ for (ControllerEndpointCredentials cec : configured) {
+ if (dbEntry.getUrl().equals(cec.getUrl())) {
+ selected = cec;
+ break;
+ }
+ }
+ // Defend against a stale database entry.
+ if (selected == null) {
+ selected = configured[0];
+ dbEntry = new ControllerEndpoint(userId, selected.getName(), selected.getUrl());
+ controllerEndpointService.updateControllerEndpointSelection(dbEntry);
+ }
+ return selected;
+ }
+
+ /**
+ * Convenience method that gets the user ID from the session and fetches the
+ * REST client. Factors code out of subclass methods.
+ *
+ * @param request
+ * HttpServletRequest
+ * @return REST client appropriate for the user
+ */
+ protected IControllerRestClient getControllerRestClient(HttpServletRequest request) throws Exception {
+ User appUser = UserUtils.getUserSession(request);
+ if (appUser == null || appUser.getLoginId() == null || appUser.getLoginId().length() == 0)
+ throw new Exception("getControllerRestClient: Failed to get application user");
+ return getControllerRestClient(appUser.getId());
+ }
+
+ /**
+ * Gets a REST client; either a mock client (returns canned data), or a real
+ * client with appropriate credentials from properties.
+ *
+ * @return REST client.
+ */
+ protected IControllerRestClient getControllerRestClient(long userId) throws Exception {
+ IControllerRestClient result = null;
+ // Be robust to missing development-only property
+ boolean mock = false;
+ if (appProperties.containsProperty(DashboardProperties.CONTROLLER_MOCK_DATA))
+ mock = appProperties.getBooleanProperty(DashboardProperties.CONTROLLER_MOCK_DATA);
+ if (mock) {
+ result = new ControllerRestClientMockImpl();
+ } else {
+ ControllerEndpointCredentials details = getOrSetControllerEndpointSelection(userId);
+ final String clearText = details.getEncryptedPassword() ? details.decryptPassword() : details.getPassword();
+ result = new ControllerRestClientImpl(details.getUrl(), details.getUsername(), clearText);
+ }
+ return result;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/ECDSingleSignOnController.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/ECDSingleSignOnController.java
new file mode 100644
index 0000000..499cb73
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/ECDSingleSignOnController.java
@@ -0,0 +1,277 @@
+package org.onap.oom.dashboard.controller;
+
+/*-
+ * ================================================================================
+ * ECOMP Portal SDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ================================================================================
+ */
+
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.openecomp.portalsdk.core.auth.LoginStrategy;
+import org.openecomp.portalsdk.core.command.LoginBean;
+import org.openecomp.portalsdk.core.controller.UnRestrictedBaseController;
+import org.openecomp.portalsdk.core.domain.User;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.menu.MenuProperties;
+import org.openecomp.portalsdk.core.onboarding.listener.PortalTimeoutHandler;
+import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants;
+import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties;
+import org.openecomp.portalsdk.core.service.LoginService;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.portalsdk.core.web.support.AppUtils;
+import org.openecomp.portalsdk.core.web.support.UserUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.util.WebUtils;
+
+@Controller
+@RequestMapping("/")
+/**
+ * Replicated from
+ * org.openecomp.portalapp.controller.core.SingleSignOnController to modify the
+ * behavior of sending user's browser on a detour of Portal app to get the
+ * EPService cookie.
+ */
+public class ECDSingleSignOnController extends UnRestrictedBaseController {
+
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ECDSingleSignOnController.class);
+
+ @Autowired
+ private LoginService loginService;
+
+ @Autowired
+ private LoginStrategy loginStrategy;
+
+ private String viewName;
+ private String welcomeView;
+
+ /**
+ * Handles requests directed to the single sign-on page by the session
+ * timeout interceptor.
+ *
+ * @param request
+ * HttpServletRequest
+ * @param response
+ * HttpServletResponse
+ * @return Redirect to an appropriate address
+ * @throws Exception
+ * On any failure
+ */
+ @RequestMapping(value = { "/single_signon.htm" }, method = RequestMethod.GET)
+ public ModelAndView singleSignOnLogin(HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+ Map<String, String> model = new HashMap<String, String>();
+ HashMap<String, String> additionalParamsMap = new HashMap<String, String>();
+ LoginBean commandBean = new LoginBean();
+
+ // SessionTimeoutInterceptor sets these parameters
+ String forwardURL = URLDecoder.decode(request.getParameter("forwardURL"), "UTF-8");
+ String redirectToPortal = request.getParameter("redirectToPortal");
+
+ if (isLoginCookieExist(request) && redirectToPortal == null) {
+ HttpSession session = null;
+ session = AppUtils.getSession(request);
+ User user = UserUtils.getUserSession(request);
+ if (session == null || user == null) {
+
+ final String authMech = SystemProperties.getProperty(SystemProperties.AUTHENTICATION_MECHANISM);
+ String userId = loginStrategy.getUserId(request);
+ commandBean.setUserid(userId);
+ commandBean = getLoginService().findUser(commandBean,
+ (String) request.getAttribute(MenuProperties.MENU_PROPERTIES_FILENAME_KEY),
+ additionalParamsMap);
+ if (commandBean.getUser() == null) {
+ String loginErrorMessage = (commandBean.getLoginErrorMessage() != null)
+ ? commandBean.getLoginErrorMessage()
+ : SystemProperties.MESSAGE_KEY_LOGIN_ERROR_USER_NOT_FOUND;
+ model.put(LoginStrategy.ERROR_MESSAGE_KEY, SystemProperties.getProperty(loginErrorMessage));
+ final String redirectUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL)
+ + "?noUserError=Yes";
+ logger.debug(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: user is null, redirect URL is {}",
+ redirectUrl);
+ return new ModelAndView("redirect:" + redirectUrl);
+ } else {
+ // store the user's information in the session
+ String loginMethod;
+ if (null == authMech || "".equals(authMech) || "BOTH".equals(authMech)) {
+ loginMethod = SystemProperties.getProperty(SystemProperties.LOGIN_METHOD_CSP);
+ } else if ("CSP".equals(authMech)) {
+ loginMethod = SystemProperties.getProperty(SystemProperties.LOGIN_METHOD_CSP);
+ } else {
+ loginMethod = SystemProperties.getProperty(SystemProperties.LOGIN_METHOD_WEB_JUNCTION);
+ }
+ UserUtils.setUserSession(request, commandBean.getUser(), commandBean.getMenu(),
+ commandBean.getBusinessDirectMenu(), loginMethod);
+ initateSessionMgtHandler(request);
+ logger.debug(EELFLoggerDelegate.debugLogger,
+ "singleSignOnLogin: create new user session for expired user {}; user {} exists in the system",
+ userId, commandBean.getUser().getOrgUserId());
+ return new ModelAndView("redirect:" + forwardURL);
+ }
+ } // user is null or session is null
+ else {
+ // both user and session are non-null.
+ logger.info(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: redirecting to the forwardURL {}",
+ forwardURL);
+ return new ModelAndView("redirect:" + forwardURL);
+ }
+ } else {
+ /*
+ * Login cookie not found, or redirect-to-portal parameter was
+ * found.
+ */
+ if (isPortalAvailable()) {
+ /*
+ * Redirect the user to the portal with a suitable return URL.
+ * The forwardURL parameter that arrives as a parameter is a
+ * partial (not absolute) request path for a page in the
+ * application. The challenge here is to compute the correct
+ * absolute path for the original request so the portal can
+ * redirect the user back to the right place. If the application
+ * sits behind WebJunction, or if separate FE-BE hosts are used,
+ * then the URL yielded by the request has a host name that is
+ * not reachable by the user.
+ */
+ String returnToAppUrl = null;
+ if (SystemProperties.containsProperty(SystemProperties.APP_BASE_URL)) {
+ // New feature as of 1610, release 3.3.3:
+ // application can publish a base URL in system.properties
+ String appUrl = SystemProperties.getProperty(SystemProperties.APP_BASE_URL);
+ returnToAppUrl = appUrl + (appUrl.endsWith("/") ? "" : "/") + forwardURL;
+ logger.debug(EELFLoggerDelegate.debugLogger,
+ "singleSignOnLogin: using app base URL {} and redirectURL {}", appUrl, returnToAppUrl);
+ } else {
+ /**
+ * Be backward compatible with applications that don't need
+ * this feature. This is the controller for the
+ * single_signon.htm page, so the replace should always find
+ * the specified token.
+ */
+ returnToAppUrl = ((HttpServletRequest) request).getRequestURL().toString()
+ .replace("single_signon.htm", forwardURL);
+ logger.debug(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: computed redirectURL {}",
+ returnToAppUrl);
+ }
+ final String encodedReturnToAppUrl = URLEncoder.encode(returnToAppUrl, "UTF-8");
+ // Also send the application's UEB key so Portal can block URL
+ // reflection attacks.
+ final String uebAppKey = PortalApiProperties.getProperty(PortalApiConstants.UEB_APP_KEY);
+ final String url = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL);
+ final String portalUrl = url.substring(0, url.lastIndexOf('/')) + "/process_csp";
+ final String redirectUrl = portalUrl + "?uebAppKey=" + uebAppKey + "&redirectUrl="
+ + encodedReturnToAppUrl;
+ logger.debug(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: portal-bound redirect URL is {}",
+ redirectUrl);
+ return new ModelAndView("redirect:" + redirectUrl);
+ } // portal is available
+
+ else {
+ /*
+ * Portal is not available. Redirect user to the login page,
+ * ignoring the forwardURL parameter.
+ */
+ return new ModelAndView("redirect:login.htm");
+ }
+
+ }
+ }
+
+ /**
+ * Discover if the portal is available by GET-ing a resource from the REST
+ * URL specified in portal.properties, using a very short timeout.
+ *
+ * @return True if the portal answers, otherwise false.
+ */
+ private boolean isPortalAvailable() {
+ HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
+ final int oneSecond = 1000;
+ httpRequestFactory.setConnectionRequestTimeout(oneSecond);
+ httpRequestFactory.setConnectTimeout(oneSecond);
+ httpRequestFactory.setReadTimeout(oneSecond);
+ RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
+ boolean avail = true;
+ try {
+ final String portalUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REST_URL);
+ String s = restTemplate.getForObject(portalUrl, String.class);
+ logger.trace("isPortalAvailable got response {}", s);
+ } catch (RestClientException ex) {
+ logger.debug("isPortalAvailable failed", ex);
+ avail = false;
+ }
+ return avail;
+ }
+
+ protected void initateSessionMgtHandler(HttpServletRequest request) {
+ String portalJSessionId = getPortalJSessionId(request);
+ String jSessionId = getJessionId(request);
+ PortalTimeoutHandler.sessionCreated(portalJSessionId, jSessionId, AppUtils.getSession(request));
+ }
+
+ public boolean isLoginCookieExist(HttpServletRequest request) {
+ Cookie ep = WebUtils.getCookie(request, LoginStrategy.EP_SERVICE);
+ return (ep != null);
+ }
+
+ public String getPortalJSessionId(HttpServletRequest request) {
+ Cookie ep = WebUtils.getCookie(request, LoginStrategy.EP_SERVICE);
+ return ep.getValue();
+ }
+
+ public String getJessionId(HttpServletRequest request) {
+ return request.getSession().getId();
+ }
+
+ public String getViewName() {
+ return viewName;
+ }
+
+ public void setViewName(String viewName) {
+ this.viewName = viewName;
+ }
+
+ public String getWelcomeView() {
+ return welcomeView;
+ }
+
+ public void setWelcomeView(String welcomeView) {
+ this.welcomeView = welcomeView;
+ }
+
+ public LoginService getLoginService() {
+ return loginService;
+ }
+
+ public void setLoginService(LoginService loginService) {
+ this.loginService = loginService;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/HealthCheckController.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/HealthCheckController.java
new file mode 100644
index 0000000..fe54790
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/controller/HealthCheckController.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.controller;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.oom.dashboard.model.HealthStatus;
+import org.openecomp.portalsdk.core.controller.UnRestrictedBaseController;
+import org.openecomp.portalsdk.core.domain.App;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.service.DataAccessService;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * This controller responds to probes for application health, returning a JSON
+ * body to indicate current status.
+ */
+@RestController
+@Configuration
+@EnableAspectJAutoProxy
+@RequestMapping("/")
+public class HealthCheckController extends UnRestrictedBaseController {
+
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(HealthCheckController.class);
+
+ private static final String HEALTH_CHECK_PATH = "/healthCheck";
+
+ @Autowired
+ private DataAccessService dataAccessService;
+
+ /**
+ * Checks application health by making a trivial query to (what??).
+ *
+ * @param request
+ * HttpServletRequest
+ * @return 200 if database access succeeds, 500 if it fails.
+ */
+ @RequestMapping(value = { HEALTH_CHECK_PATH }, method = RequestMethod.GET, produces = "application/json")
+ public HealthStatus healthCheck(HttpServletRequest request) {
+ logger.setRequestBasedDefaultsIntoGlobalLoggingContext(request, DashboardRestrictedBaseController.APP_NAME);
+ logger.info(EELFLoggerDelegate.auditLogger, request.getMethod() + request.getRequestURI());
+ HealthStatus healthStatus = null;
+ try {
+ logger.debug(EELFLoggerDelegate.debugLogger, "Performing health check");
+ @SuppressWarnings("unchecked")
+ // Get the single app.
+ List<App> list = dataAccessService.getList(App.class, null);
+ if (list.size() > 0)
+ healthStatus = new HealthStatus(200, SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME) + " health check succeeded");
+ else
+ healthStatus = new HealthStatus(500, SystemProperties.getProperty(SystemProperties.APP_DISPLAY_NAME) + " health check failed to run db query");
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "Failed to perform health check", ex);
+ healthStatus = new HealthStatus(500, "health check failed: " + ex.toString());
+ }
+ return healthStatus;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/domain/ControllerEndpoint.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/domain/ControllerEndpoint.java
new file mode 100644
index 0000000..33a22d0
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/domain/ControllerEndpoint.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.domain;
+
+import org.openecomp.portalsdk.core.domain.support.DomainVo;
+
+/**
+ * Model for controller endpoint information stored in database. A single row
+ * for a user represents a selected endpoint.
+ */
+public class ControllerEndpoint extends DomainVo {
+
+ private static final long serialVersionUID = 8785223545128054402L;
+
+ private long userId;
+ private String name;
+ private String url;
+
+ public ControllerEndpoint() {
+ }
+
+ public ControllerEndpoint(long userId, String name, String url) {
+ this.userId = userId;
+ this.name = name;
+ this.url = url;
+ }
+
+ public long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(long userId) {
+ this.userId = userId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprint.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprint.java
new file mode 100644
index 0000000..df02cc2
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprint.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model with fields only for the top-level attributes. All complex child
+ * structures are represented as generic collections.
+ */
+public final class CloudifyBlueprint extends ECTransportModel {
+
+ /** A unique identifier for the blueprint. */
+ public final String id;
+ /** The blueprint’s main file name. */
+ public final String main_file_name;
+ /** The blueprint’s description. */
+ public final String description;
+ /** The time the blueprint was uploaded to the manager. */
+ public final String created_at;
+ /** The last time the blueprint was updated. */
+ public final String updated_at;
+ /** The parsed result of the blueprint. */
+ public final Map<String, Object> plan;
+
+ @JsonCreator
+ public CloudifyBlueprint(@JsonProperty("main_file_name") String main_file_name,
+ @JsonProperty("description") String description, @JsonProperty("created_at") String created_at,
+ @JsonProperty("updated_at") String updated_at, @JsonProperty("id") String id,
+ @JsonProperty("plan") Map<String, Object> plan) {
+ this.main_file_name = main_file_name;
+ this.description = description;
+ this.created_at = created_at;
+ this.updated_at = updated_at;
+ this.id = id;
+ this.plan = plan;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintContent.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintContent.java
new file mode 100644
index 0000000..89c3c38
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintContent.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Trivial wrapper for Blueprint YAML content.
+ */
+public final class CloudifyBlueprintContent extends ECTransportModel {
+
+ /** A unique identifier for the blueprint. */
+ public final String id;
+ /** The content of the blueprint as YAML */
+ public final String content;
+
+ @JsonCreator
+ public CloudifyBlueprintContent(@JsonProperty("id") String id,
+ @JsonProperty("content") String content) {
+ this.id = id;
+ this.content = content;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintList.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintList.java
new file mode 100644
index 0000000..933d0d3
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintList.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class CloudifyBlueprintList extends ECTransportModel {
+
+ public final List<CloudifyBlueprint> items;
+ public final Metadata metadata;
+
+ @JsonCreator
+ public CloudifyBlueprintList(@JsonProperty("items") List<CloudifyBlueprint> items, @JsonProperty("metadata") Metadata metadata){
+ this.items = items;
+ this.metadata = metadata;
+ }
+
+ public static final class Metadata {
+ public final Pagination pagination;
+
+ @JsonCreator
+ public Metadata(@JsonProperty("pagination") Pagination pagination){
+ this.pagination = pagination;
+ }
+
+ public static final class Pagination {
+ public final long total;
+ public final long offset;
+ public final long size;
+
+ @JsonCreator
+ public Pagination(@JsonProperty("total") long total, @JsonProperty("offset") long offset, @JsonProperty("size") long size){
+ this.total = total;
+ this.offset = offset;
+ this.size = size;
+ }
+ }
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintUpload.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintUpload.java
new file mode 100644
index 0000000..2d63d92
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyBlueprintUpload.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model for message POST-ed to controller to create a Cloudify Blueprint:
+ *
+ * <pre>
+ {
+ "blueprint_id" : "blueprint-id",
+ "blueprint_filename" : "name.yaml",
+ "zip_url" : "url"
+ }
+ * </pre>
+ */
+public final class CloudifyBlueprintUpload extends ECTransportModel {
+
+ /** A unique identifier for the blueprint. */
+ public final String blueprint_id;
+ /** The blueprint’s main file name. */
+ public final String blueprint_filename;
+ /** The zip file URL. */
+ public final String zip_url;
+
+ @JsonCreator
+ public CloudifyBlueprintUpload(@JsonProperty("blueprint_id") String blueprint_id,
+ @JsonProperty("blueprint_filename") String blueprint_filename, @JsonProperty("zip_url") String zip_url) {
+ this.blueprint_id = blueprint_id;
+ this.blueprint_filename = blueprint_filename;
+ this.zip_url = zip_url;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeployment.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeployment.java
new file mode 100644
index 0000000..b4dc65c
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeployment.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model with fields only for the top-level attributes. All complex child
+ * structures are represented simply as generic collections.
+ */
+public final class CloudifyDeployment extends ECTransportModel {
+
+ /** A unique identifier for the deployment. */
+ public final String id;
+ public final String description;
+ /** The id of the blueprint the deployment is based on. */
+ public final String blueprint_id;
+ /** The time when the deployment was created. */
+ public final String created_at;
+ /** The time the deployment was last updated at. */
+ public final String updated_at;
+ /**
+ * A dictionary containing key value pairs which represents a deployment
+ * input and its provided value.
+ */
+ public final Inputs inputs;
+ /** A dictionary containing policies of a deployment. */
+ public final Map<String, Object> policy_types;
+ /** A dictionary containing policy triggers of a deployment. */
+ public final Map<String, Object> policy_triggers;
+ /** A dictionary containing an outputs definition of a deployment. */
+ public final Map<String, Object> outputs;
+ /** A dictionary containing the groups definition of deployment. */
+ public final Map<String, Object> groups;
+
+ public final Map<String, Object> scaling_groups;
+ /** A list of workflows that can be executed on a deployment. */
+ public final List<Workflow> workflows;
+
+ @JsonCreator
+ public CloudifyDeployment(@JsonProperty("description") String description,
+ @JsonProperty("blueprint_id") String blueprint_id, @JsonProperty("created_at") String created_at,
+ @JsonProperty("updated_at") String updated_at, @JsonProperty("id") String id,
+ @JsonProperty("inputs") Inputs inputs, @JsonProperty("policy_types") Map<String, Object> policy_types,
+ @JsonProperty("policy_triggers") Map<String, Object> policy_triggers,
+ @JsonProperty("outputs") Map<String, Object> outputs, @JsonProperty("groups") Map<String, Object> groups,
+ @JsonProperty("scaling_groups") Map<String, Object> scaling_groups,
+ @JsonProperty("workflows") List<Workflow> workflows) {
+ this.description = description;
+ this.blueprint_id = blueprint_id;
+ this.created_at = created_at;
+ this.updated_at = updated_at;
+ this.id = id;
+ this.inputs = inputs;
+ this.policy_types = policy_types;
+ this.policy_triggers = policy_triggers;
+ this.outputs = outputs;
+ this.groups = groups;
+ this.scaling_groups = scaling_groups;
+ this.workflows = workflows;
+ }
+
+ public static final class Inputs {
+ public final String openstack_auth_url;
+ public final String external_network_name;
+ public final String openstack_username;
+ public final String instance_image;
+ public final String keypair_name;
+ public final String instance_name;
+ public final String keypair_private_key_path;
+ public final String openstack_tenant_name;
+ public final String subnet_name;
+ public final String openstack_region;
+ public final String openstack_password;
+ public final String ssh_username;
+ public final String instance_flavor;
+ public final String network_name;
+
+ @JsonCreator
+ public Inputs(@JsonProperty("openstack_auth_url") String openstack_auth_url,
+ @JsonProperty("external_network_name") String external_network_name,
+ @JsonProperty("openstack_username") String openstack_username,
+ @JsonProperty("instance_image") String instance_image,
+ @JsonProperty("keypair_name") String keypair_name, @JsonProperty("instance_name") String instance_name,
+ @JsonProperty("keypair_private_key_path") String keypair_private_key_path,
+ @JsonProperty("openstack_tenant_name") String openstack_tenant_name,
+ @JsonProperty("subnet_name") String subnet_name,
+ @JsonProperty("openstack_region") String openstack_region,
+ @JsonProperty("openstack_password") String openstack_password,
+ @JsonProperty("ssh_username") String ssh_username,
+ @JsonProperty("instance_flavor") String instance_flavor,
+ @JsonProperty("network_name") String network_name) {
+
+ this.openstack_auth_url = openstack_auth_url;
+ this.external_network_name = external_network_name;
+ this.openstack_username = openstack_username;
+ this.instance_image = instance_image;
+ this.keypair_name = keypair_name;
+ this.instance_name = instance_name;
+ this.keypair_private_key_path = keypair_private_key_path;
+ this.openstack_tenant_name = openstack_tenant_name;
+ this.subnet_name = subnet_name;
+ this.openstack_region = openstack_region;
+ this.openstack_password = openstack_password;
+ this.ssh_username = ssh_username;
+ this.instance_flavor = instance_flavor;
+ this.network_name = network_name;
+ }
+ }
+
+ public static final class Workflow {
+ public final String name;
+ public final String created_at;
+ public final Map<String,Parameter> parameters;
+
+ @JsonCreator
+ public Workflow(@JsonProperty("name") String name, @JsonProperty("created_at") String created_at,
+ @JsonProperty("parameters") Map<String,Parameter> parameters) {
+ this.name = name;
+ this.created_at = created_at;
+ this.parameters = parameters;
+ }
+ }
+
+ public static final class Parameter {
+
+ @JsonProperty("default")
+ public final Object xdefault;
+ public final String description;
+
+ @JsonCreator
+ public Parameter(@JsonProperty("default") Object xdefault, @JsonProperty("description") String description) {
+ this.xdefault = xdefault;
+ this.description = description;
+ }
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeploymentList.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeploymentList.java
new file mode 100644
index 0000000..f57784f
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeploymentList.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class CloudifyDeploymentList extends ECTransportModel {
+
+ public final List<CloudifyDeployment> items;
+ public final Metadata metadata;
+
+ @JsonCreator
+ public CloudifyDeploymentList(@JsonProperty("items") List<CloudifyDeployment> items, @JsonProperty("metadata") Metadata metadata){
+ this.items = items;
+ this.metadata = metadata;
+ }
+
+ public static final class Metadata {
+ public final Pagination pagination;
+
+ @JsonCreator
+ public Metadata(@JsonProperty("pagination") Pagination pagination){
+ this.pagination = pagination;
+ }
+
+ public static final class Pagination {
+ public final long total;
+ public final long offset;
+ public final long size;
+
+ @JsonCreator
+ public Pagination(@JsonProperty("total") long total, @JsonProperty("offset") long offset, @JsonProperty("size") long size){
+ this.total = total;
+ this.offset = offset;
+ this.size = size;
+ }
+ }
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeploymentRequest.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeploymentRequest.java
new file mode 100644
index 0000000..0bc7b44
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyDeploymentRequest.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model for message POST-ed to controller to create a Cloudify Deployment:
+ *
+ * <pre>
+ {
+ "deployment_id" : "deployment-id",
+ "blueprint_id" : "blueprint-id",
+ "parameters" :
+ {
+ "p1" : "v1"
+ }
+ }
+ * </pre>
+ */
+public final class CloudifyDeploymentRequest extends ECTransportModel {
+
+ /** A unique identifier for the deployment. */
+ public final String deployment_id;
+ /** A unique identifier for the blueprint. */
+ public final String blueprint_id;
+ /**
+ * These values are input for the deployment which can be retrieved from the
+ * GET /blueprint API this is :plan.input field in GET /blueprint
+ */
+ public final Map<String, Object> parameters;
+
+ @JsonCreator
+ public CloudifyDeploymentRequest(@JsonProperty("deployment_id") String deployment_id,
+ @JsonProperty("blueprint_id") String blueprint_id,
+ @JsonProperty("parameters") Map<String, Object> parameters) {
+ this.deployment_id = deployment_id;
+ this.blueprint_id = blueprint_id;
+ this.parameters = parameters;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecution.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecution.java
new file mode 100644
index 0000000..d580ef0
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecution.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model with fields only for the top-level attributes. All complex child
+ * structures are represented simply as generic collections.
+ */
+public final class CloudifyExecution extends ECTransportModel {
+
+ /** A unique identifier for the execution. */
+ public final String id;
+ /** The executions status. */
+ public final String status;
+ /** The time the execution was queued at. */
+ public final String created_at;
+ /** The id/name of the workflow the execution is of. */
+ public final String workflow_id;
+ /** true if the execution is of a system workflow. */
+ public final Boolean is_system_workflow;
+ /** The id of the blueprint the execution is in the context of. */
+ public final String blueprint_id;
+ /** The id of the deployment the execution is in the context of. */
+ public final String deployment_id;
+ /** The execution’s error message on execution failure. */
+ public final String error;
+ /** A dict of the workflow parameters passed when starting the execution. */
+ public final Map<String, Object> parameters;
+
+ @JsonCreator
+ public CloudifyExecution(@JsonProperty("status") String status, @JsonProperty("created_at") String created_at,
+ @JsonProperty("workflow_id") String workflow_id,
+ @JsonProperty("is_system_workflow") Boolean is_system_workflow,
+ @JsonProperty("blueprint_id") String blueprint_id, @JsonProperty("deployment_id") String deployment_id,
+ @JsonProperty("error") String error, @JsonProperty("id") String id,
+ @JsonProperty("parameters") Map<String, Object> parameters) {
+
+ this.status = status;
+ this.created_at = created_at;
+ this.workflow_id = workflow_id;
+ this.is_system_workflow = is_system_workflow;
+ this.blueprint_id = blueprint_id;
+ this.deployment_id = deployment_id;
+ this.error = error;
+ this.id = id;
+ this.parameters = parameters;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecutionList.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecutionList.java
new file mode 100644
index 0000000..6d97c94
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecutionList.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class CloudifyExecutionList extends ECTransportModel {
+
+ public final List<CloudifyExecution> items;
+ public final Metadata metadata;
+
+ @JsonCreator
+ public CloudifyExecutionList(@JsonProperty("items") List<CloudifyExecution> items, @JsonProperty("metadata") Metadata metadata){
+ this.items = items;
+ this.metadata = metadata;
+ }
+
+ public static final class Metadata {
+ public final Pagination pagination;
+
+ @JsonCreator
+ public Metadata(@JsonProperty("pagination") Pagination pagination){
+ this.pagination = pagination;
+ }
+
+ public static final class Pagination {
+ public final long total;
+ public final long offset;
+ public final long size;
+
+ @JsonCreator
+ public Pagination(@JsonProperty("total") long total, @JsonProperty("offset") long offset, @JsonProperty("size") long size){
+ this.total = total;
+ this.offset = offset;
+ this.size = size;
+ }
+ }
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecutionRequest.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecutionRequest.java
new file mode 100644
index 0000000..13b6826
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/CloudifyExecutionRequest.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model for message POST-ed to controller to create a Cloudify Execution:
+ *
+ * <pre>
+ * {
+ "deployment_id" : "deployment-id",
+ "workflow_name" : "workflow-name",
+ "allow_custom_parameter" : "true|false",
+ "force" : "true|false",
+ "parameters":
+ {
+
+ }
+ }
+ * </pre>
+ */
+public final class CloudifyExecutionRequest extends ECTransportModel {
+
+ /** A unique identifier for the deployment. */
+ public final String deployment_id;
+ /** A unique identifier for the workflow */
+ public final String workflow_name;
+ public final Boolean allow_custom_parameter;
+ public final Boolean force;
+ /** Parameters: retrieve using the GET /deployments */
+ public final Map<String, Object> parameters;
+
+ @JsonCreator
+ public CloudifyExecutionRequest(@JsonProperty("deployment_id") String deployment_id,
+ @JsonProperty("workflow_name") String workflow_name,
+ @JsonProperty("allow_custom_parameter") Boolean allowCustomParameter, @JsonProperty("force") Boolean force,
+ @JsonProperty("parameters") Map<String, Object> parameters) {
+ this.deployment_id = deployment_id;
+ this.workflow_name = workflow_name;
+ this.allow_custom_parameter = allowCustomParameter;
+ this.force = force;
+ this.parameters = parameters;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulDatacenter.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulDatacenter.java
new file mode 100644
index 0000000..93eb224
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulDatacenter.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model for message returned by Consul about monitored datacenters.
+ *
+ * <pre>
+ "dcname"
+ </pre>
+ */
+public final class ConsulDatacenter extends ECTransportModel {
+
+ public final String name;
+
+ @JsonCreator
+ public ConsulDatacenter(
+ @JsonProperty("ID") String name) {
+ this.name = name;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulHealthServiceRegistration.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulHealthServiceRegistration.java
new file mode 100644
index 0000000..1385de9
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulHealthServiceRegistration.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model for message POST-ed to controller to (de)register a node or service
+ * with the Consul health service. The ID is optional; the name is required.
+ *
+ * <pre>
+{
+ "services": [
+ {
+ "id": "<service_id>",
+ "name": "<service_name>",
+ "address": "<service_address>",
+ "port": "<service_port>",
+ "tags": [
+ ],
+ "checks": [
+ {
+ "endpoint": "<http url for status>",
+ "interval": "<frequency to check health> e.g., 10s|10m",
+ "description": "<human readable description of the check",
+ "name":"<name of the check>
+ },
+ {
+ "endpoint": "<http url for status>",
+ "interval": "<frequency to check health> e.g. 10s|10m",
+ "description": "<human readable description of the check",
+ "name":"<name of the check>
+ },
+ ]
+ }
+ ]
+}*
+ * </pre>
+ */
+public final class ConsulHealthServiceRegistration extends ECTransportModel {
+
+ public final List<ConsulServiceRegistration> services;
+
+ @JsonCreator
+ public ConsulHealthServiceRegistration(@JsonProperty("services") List<ConsulServiceRegistration> services) {
+ this.services = services;
+ }
+
+ public static final class ConsulServiceRegistration {
+
+ public final String id;
+ public final String name;
+ public final String address;
+ public final String port;
+ public final List<String> tags;
+ public final List<EndpointCheck> checks;
+
+ @JsonCreator
+ public ConsulServiceRegistration(@JsonProperty("id") String id, //
+ @JsonProperty("name") String name, //
+ @JsonProperty("address") String address, //
+ @JsonProperty("port") String port, //
+ @JsonProperty("tags") List<String> tags,//
+ @JsonProperty("checks") List<EndpointCheck> checks) {
+ this.id = id;
+ this.name = name;
+ this.address = address;
+ this.port = port;
+ this.tags = tags;
+ this.checks = checks;
+ }
+
+ }
+
+ public static final class EndpointCheck {
+
+ public final String endpoint;
+ public final String interval;
+ public final String description;
+ public final String name;
+
+ @JsonCreator
+ public EndpointCheck(@JsonProperty("endpoint") String endpoint, //
+ @JsonProperty("interval") String interval, //
+ @JsonProperty("description") String description, //
+ @JsonProperty("name") String name) {
+ this.endpoint = endpoint;
+ this.interval = interval;
+ this.description = description;
+ this.name = name;
+ }
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulNodeInfo.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulNodeInfo.java
new file mode 100644
index 0000000..4235cd9
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulNodeInfo.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model for message returned by Consul about a node registered for health monitoring.
+ *
+ * <pre>
+ {
+ "ID":"a2788806-6e2e-423e-8ee7-6cad6f3d3de6",
+ "Node":"cjlvmcnsl00",
+ "Address":"10.170.8.13",
+ "TaggedAddresses":{"lan":"10.170.8.13","wan":"10.170.8.13"},
+ "Meta":{},
+ "CreateIndex":6,
+ "ModifyIndex":179808
+ }
+ </pre>
+ */
+public final class ConsulNodeInfo extends ECTransportModel {
+
+ public final String id;
+ public final String node;
+ public final String address;
+ public final Map<String,Object> taggedAddresses;
+ public final Map<String,Object> meta;
+ public final int createIndex;
+ public final int modifyIndex;
+
+ @JsonCreator
+ public ConsulNodeInfo(
+ @JsonProperty("ID") String id,
+ @JsonProperty("Node") String node,
+ @JsonProperty("Address") String address,
+ @JsonProperty("TaggedAddresses") Map<String,Object> taggedAddresses,
+ @JsonProperty("Meta") Map<String,Object> meta,
+ @JsonProperty("CreateIndex") int createIndex,
+ @JsonProperty("ModifyIndex") int modifyIndex) {
+ this.id = id;
+ this.node = node;
+ this.address = address;
+ this.taggedAddresses = taggedAddresses;
+ this.meta = meta;
+ this.createIndex = createIndex;
+ this.modifyIndex = modifyIndex;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceHealth.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceHealth.java
new file mode 100644
index 0000000..5d019cf
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceHealth.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model for message returned by Consul about health of a service.
+ *
+ * <pre>
+ {
+ "Node": "cjlvmcnsl00",
+ "CheckID": "service:pgaas1_Service_ID",
+ "Name": "Service 'pgaasServer1' check",
+ "Status": "passing",
+ "Notes": "This is a pgaas1_Service_ID health check",
+ "Output": "HTTP GET http:\/\/1.2.3.4:8000\/healthcheck\/status: 200 OK ..",
+ "ServiceID": "pgaas1_Service_ID",
+ "ServiceName": "pgaasServer1",
+ "CreateIndex": 190199,
+ "ModifyIndex": 199395
+ } </pre>
+ *
+ */
+public final class ConsulServiceHealth extends ECTransportModel {
+
+ public final String node;
+ public final String checkID;
+ public final String name;
+ public final String status;
+ public final String notes;
+ public final String output;
+ public final String serviceID;
+ public final String serviceName;
+ public final int createIndex;
+ public final int modifyIndex;
+
+ @JsonCreator
+ public ConsulServiceHealth(
+ @JsonProperty("Node") String node,
+ @JsonProperty("CheckID") String checkID,
+ @JsonProperty("Name") String name,
+ @JsonProperty("Status") String status,
+ @JsonProperty("Notes") String notes,
+ @JsonProperty("Output") String output,
+ @JsonProperty("ServiceID") String serviceID,
+ @JsonProperty("ServiceName") String serviceName,
+ @JsonProperty("CreateIndex") int createIndex,
+ @JsonProperty("ModifyIndex") int modifyIndex) {
+ this.node = node;
+ this.checkID = checkID;
+ this.name = name;
+ this.status = status;
+ this.notes = notes;
+ this.output = output;
+ this.serviceID = serviceID;
+ this.serviceName = serviceName;
+ this.createIndex = createIndex;
+ this.modifyIndex = modifyIndex;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceHealthHistory.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceHealthHistory.java
new file mode 100644
index 0000000..4ad75e6
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceHealthHistory.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Model for message returned by Consul about health of a service observed at
+ * some point in time.
+ *
+ * <pre>
+ {
+ "Status": "critical",
+ "Output": "\"Get http://1.2.3.4:8080: dial tcp 2.3.4.5:8080: getsockopt: connection refused\"",
+ "Date": "2017-06-01 15:31:58.00-0000"
+ }
+ * </pre>
+ *
+ */
+public final class ConsulServiceHealthHistory extends ECTransportModel {
+
+ public final String status;
+ public final String output;
+ public final String date;
+
+ @JsonCreator
+ public ConsulServiceHealthHistory(@JsonProperty("Status") String status, @JsonProperty("Output") String output,
+ @JsonProperty("Date") String date) {
+ this.status = status;
+ this.output = output;
+ this.date = date;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceInfo.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceInfo.java
new file mode 100644
index 0000000..3b4ad40
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ConsulServiceInfo.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Dashboard-specific model for message about a service registered for health
+ * monitoring. This is NOT a model of message returned by Controller.
+ *
+ * The controller API answers a message with a map of String (name) to List of
+ * String (IP addresses).
+ *
+ * <pre>
+ {
+ "pgaasServer1":["1.2.3.4"]
+ }
+ * </pre>
+ */
+public final class ConsulServiceInfo extends ECTransportModel {
+
+ public final String name;
+ public final List<String> addresses;
+
+ @JsonCreator
+ public ConsulServiceInfo(@JsonProperty("name") String name, @JsonProperty("addresses") List<String> addresses) {
+ this.name = name;
+ this.addresses = addresses;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ControllerEndpointCredentials.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ControllerEndpointCredentials.java
new file mode 100644
index 0000000..caa8aa7
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ControllerEndpointCredentials.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import org.openecomp.portalsdk.core.onboarding.util.CipherUtil;
+
+/**
+ * Model with Controller username and password for use only within the back end;
+ * never serialized as JSON.
+ */
+public class ControllerEndpointCredentials extends ControllerEndpointTransport {
+
+ public String username;
+ public String password;
+ public boolean isEncryptedPass;
+
+ public ControllerEndpointCredentials(boolean selected, String name, String url, String username, String password,
+ boolean isEncryptedPass) {
+ super(selected, name, url);
+ this.username = username;
+ this.password = password;
+ this.isEncryptedPass = isEncryptedPass;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public boolean getEncryptedPassword() {
+ return isEncryptedPass;
+ }
+
+ public void setEncryptedPassword(boolean isEncryptedPass) {
+ this.isEncryptedPass = isEncryptedPass;
+ }
+
+ /**
+ * Convenience method to yield a ControllerEndpointTransport object.
+ *
+ * @return ControllerEndpoint with copy of the non-privileged data
+ */
+ public ControllerEndpointTransport toControllerEndpointTransport() {
+ return new ControllerEndpointTransport(getSelected(), getName(), getUrl());
+ }
+
+ /**
+ * Accepts clear text and stores an encrypted value; as a side effect, sets
+ * the encrypted flag to true.
+ *
+ * @param plainText
+ * Clear-text password
+ * @throws Exception
+ * If encryption fails
+ */
+ public void encryptPassword(final String plainText) throws Exception {
+ this.password = CipherUtil.encrypt(plainText);
+ this.isEncryptedPass = true;
+ }
+
+ /**
+ * Client should call this method if {@link #getEncryptedPassword()} returns
+ * true.
+ *
+ * @return Clear-text password.
+ * @throws Exception
+ * If decryption fails
+ */
+ public String decryptPassword() throws Exception {
+ return CipherUtil.decrypt(password);
+ }
+} \ No newline at end of file
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ControllerEndpointTransport.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ControllerEndpointTransport.java
new file mode 100644
index 0000000..94a88f8
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ControllerEndpointTransport.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+/**
+ * Model for message passed by backend to frontend about ECOMP-C Endpoints.
+ */
+public class ControllerEndpointTransport extends ECTransportModel {
+
+ private boolean selected;
+ private String name;
+ private String url;
+
+ public ControllerEndpointTransport() {}
+
+ public ControllerEndpointTransport(boolean selected, String name, String url) {
+ this.selected = selected;
+ this.name = name;
+ this.url = url;
+ }
+
+ public boolean getSelected() {
+ return selected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ECTransportModel.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ECTransportModel.java
new file mode 100644
index 0000000..1c498eb
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/ECTransportModel.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+
+/**
+ * Base class for POJOs that transport data in the ECOMP Controller webapp.
+ */
+public abstract class ECTransportModel {
+
+ protected final ObjectMapper mapper = new ObjectMapper();
+
+ public ECTransportModel() {
+ // Do not serialize null values
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ // toString should yield pretty version
+ mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
+ // tolerate empty strings where object is expected
+ mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
+ }
+
+ /**
+ * Convenience method that serializes content as JSON and catches any
+ * exception so this method can be easily used in a catch clause.
+ *
+ * @return A REST error response object as well-formed JSON
+ */
+ public String toString() {
+ String json = null;
+ try {
+ json = mapper.writeValueAsString(this);
+ } catch (JsonProcessingException jpe) {
+ // Should never, ever happen
+ json = "{ \"error\" : \"" + jpe.toString() + "\"}";
+ }
+ return json;
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/HealthStatus.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/HealthStatus.java
new file mode 100644
index 0000000..6d6a0e4
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/HealthStatus.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+/**
+ * Model for JSON response with health-check results.
+ */
+public class HealthStatus {
+ // Either 200 or 500
+ public int statusCode;
+ // Additional detail in case of error, empty in case of success.
+ public String message;
+
+ public HealthStatus(int code, String msg) {
+ this.statusCode = code;
+ this.message = msg;
+ }
+
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ public void setStatusCode(int code) {
+ this.statusCode = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String msg) {
+ this.message = msg;
+ }
+} \ No newline at end of file
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponseError.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponseError.java
new file mode 100644
index 0000000..0b4f5b8
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponseError.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Trivial model for carrying error responses.
+ */
+public class RestResponseError extends ECTransportModel {
+
+ private String error;
+
+ public RestResponseError() {
+ }
+
+ /**
+ * Convenience constructor
+ *
+ * @param message
+ * Message body
+ */
+ public RestResponseError(final String message) {
+ this.error = message;
+ }
+
+ /**
+ * Convenience constructor that limits the size of the throwable message.
+ *
+ * @param message
+ * Message body
+ * @param t
+ * Throwable used to construct body
+ */
+ public RestResponseError(final String message, final Throwable t) {
+ final int enough = 512;
+ String exString = t.toString();
+ String exceptionMsg = exString.length() > enough ? exString.substring(0, enough) : exString;
+ this.error = message + ": " + exceptionMsg;
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String message) {
+ this.error = message;
+ }
+
+ /**
+ * Convenience method that serializes content as JSON and catches any
+ * exception so this can be easily used in a catch clause.
+ *
+ * @return A REST error response object as well-formed JSON
+ */
+ public String toJson() {
+ String json = null;
+ try {
+ ObjectMapper mapper = new ObjectMapper();
+ json = mapper.writeValueAsString(this);
+ } catch (JsonProcessingException jpe) {
+ // Should never, ever happen
+ json = "{ \"error\" : \"" + jpe.toString() + "\"}";
+ }
+ return json;
+ }
+
+ @Override
+ public String toString() {
+ return "RestErrorResponse[message=" + error + "]";
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponsePage.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponsePage.java
new file mode 100644
index 0000000..1fe8e29
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponsePage.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+/**
+ * Model for a response with count of items available, count of pages required
+ * to display all items, and one page worth of data items.
+ *
+ * @param <T>
+ * Model class for item
+ */
+public class RestResponsePage<T> extends ECTransportModel {
+
+ private int totalItems;
+ private int totalPages;
+ private T items;
+
+ public RestResponsePage() {
+ }
+
+ public RestResponsePage(final int totalItems, final int totalPages, final T items) {
+ this.totalItems = totalItems;
+ this.totalPages = totalPages;
+ this.items = items;
+ }
+
+ public int getTotalItems() {
+ return totalItems;
+ }
+
+ public void setTotalItems(int items) {
+ this.totalItems = items;
+ }
+
+ public int getTotalPages() {
+ return totalPages;
+ }
+
+ public void setTotalPages(int pages) {
+ this.totalPages = pages;
+ }
+
+ public T getItems() {
+ return items;
+ }
+
+ public void setItems(final T data) {
+ this.items = data;
+ }
+
+ @Override
+ public String toString() {
+ return "RestResponsePage[totalItems=" + totalItems + ", totalPages=" + totalPages + ", items=" + items + "]";
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponseSuccess.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponseSuccess.java
new file mode 100644
index 0000000..655fcf0
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/model/RestResponseSuccess.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.model;
+
+/**
+ * Trivial model for carrying a message indicating success.
+ */
+public class RestResponseSuccess extends ECTransportModel {
+
+ private String message;
+
+ public RestResponseSuccess() {
+ }
+
+ /**
+ * Convenience constructor
+ *
+ * @param message
+ * Message body
+ */
+ public RestResponseSuccess(final String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ @Override
+ public String toString() {
+ return "RestResponseSuccess[message=" + message + "]";
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientImpl.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientImpl.java
new file mode 100644
index 0000000..13889b2
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientImpl.java
@@ -0,0 +1,425 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.rest;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.onap.oom.dashboard.model.CloudifyBlueprintContent;
+import org.onap.oom.dashboard.model.CloudifyBlueprintList;
+import org.onap.oom.dashboard.model.CloudifyBlueprintUpload;
+import org.onap.oom.dashboard.model.CloudifyDeploymentList;
+import org.onap.oom.dashboard.model.CloudifyDeploymentRequest;
+import org.onap.oom.dashboard.model.CloudifyExecution;
+import org.onap.oom.dashboard.model.CloudifyExecutionList;
+import org.onap.oom.dashboard.model.CloudifyExecutionRequest;
+import org.onap.oom.dashboard.model.ConsulDatacenter;
+import org.onap.oom.dashboard.model.ConsulHealthServiceRegistration;
+import org.onap.oom.dashboard.model.ConsulNodeInfo;
+import org.onap.oom.dashboard.model.ConsulServiceHealth;
+import org.onap.oom.dashboard.model.ConsulServiceHealthHistory;
+import org.onap.oom.dashboard.model.ConsulServiceInfo;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Provides methods for accessing the ECOMP Controller API via REST. Most
+ * methods are just simple proxies. Only the methods that fetch one page of data
+ * have to do any real work.
+ *
+ * Implemented using Spring RestTemplate. Supports basic HTTP authentication.
+ *
+ */
+public class ControllerRestClientImpl implements IControllerRestClient {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ControllerRestClientImpl.class);
+
+ private final String baseUrl;
+ private final RestTemplate restTemplate;
+ private final ObjectMapper objectMapper = new ObjectMapper();
+
+ /**
+ * Builds a restTemplate. If username and password are supplied, uses basic
+ * HTTP authentication.
+ *
+ * @param webapiUrl
+ * URL of the web endpoint
+ * @param user
+ * user name; ignored if null
+ * @param pass
+ * password
+ */
+ public ControllerRestClientImpl(String webapiUrl, String user, String pass) {
+ if (webapiUrl == null)
+ throw new IllegalArgumentException("Null URL not permitted");
+
+ URL url = null;
+ try {
+ url = new URL(webapiUrl);
+ baseUrl = url.toExternalForm();
+ } catch (MalformedURLException ex) {
+ throw new RuntimeException("Failed to parse URL", ex);
+ }
+ final HttpHost httpHost = new HttpHost(url.getHost(), url.getPort());
+
+ // Build a client with a credentials provider
+ CloseableHttpClient httpClient = null;
+ if (user != null && pass != null) {
+ CredentialsProvider credsProvider = new BasicCredentialsProvider();
+ credsProvider.setCredentials(new AuthScope(httpHost), new UsernamePasswordCredentials(user, pass));
+ httpClient = HttpClientBuilder.create().setDefaultCredentialsProvider(credsProvider).build();
+ } else {
+ httpClient = HttpClientBuilder.create().build();
+ }
+ // Create request factory
+ HttpComponentsClientHttpRequestFactoryBasicAuth requestFactory = new HttpComponentsClientHttpRequestFactoryBasicAuth(
+ httpHost);
+ requestFactory.setHttpClient(httpClient);
+
+ // Put the factory in the template
+ this.restTemplate = new RestTemplate();
+ restTemplate.setRequestFactory(requestFactory);
+ }
+
+ /**
+ * Builds URL ensuring appropriate separators. The base comes from
+ * properties file so could have many problems.
+ *
+ * @param base
+ * @param suffix
+ * @param queryParams
+ * key-value pairs; i.e. must have an even number of entries.
+ * Ignored if null.
+ * @return
+ */
+ private String buildUrl(final String[] path, final String[] queryParams) {
+ StringBuilder sb = new StringBuilder(path[0]);
+ for (int p = 1; p < path.length; ++p) {
+ if (!path[p - 1].endsWith("/") && !path[p].startsWith("/"))
+ sb.append('/');
+ sb.append(path[p]);
+ }
+ if (queryParams != null && queryParams.length > 0) {
+ sb.append('?');
+ int i = 0;
+ while (i < queryParams.length) {
+ if (i > 0)
+ sb.append('&');
+ sb.append(queryParams[i]);
+ sb.append('=');
+ sb.append(queryParams[i + 1]);
+ i += 2;
+ }
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public CloudifyBlueprintList getBlueprints() {
+ String url = buildUrl(new String[] { baseUrl, blueprintsPath }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "getBlueprints: url {}", url);
+ ResponseEntity<CloudifyBlueprintList> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<CloudifyBlueprintList>() {
+ });
+ CloudifyBlueprintList result = response.getBody();
+ return result;
+ }
+
+ @Override
+ public CloudifyBlueprintList getBlueprint(final String id) {
+ String url = buildUrl(new String[] { baseUrl, blueprintsPath }, new String[] { "id", id });
+ logger.debug(EELFLoggerDelegate.debugLogger, "getBlueprint: url {}", url);
+ ResponseEntity<CloudifyBlueprintList> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<CloudifyBlueprintList>() {
+ });
+ CloudifyBlueprintList result = response.getBody();
+ return result;
+ }
+
+ @Override
+ public CloudifyBlueprintContent viewBlueprint(final String id) {
+ String url = buildUrl(new String[] { baseUrl, viewBlueprintsPath }, new String[] { "id", id });
+ logger.debug(EELFLoggerDelegate.debugLogger, "viewBlueprint: url {}", url);
+ ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
+ String yaml = response.getBody();
+ CloudifyBlueprintContent result = new CloudifyBlueprintContent(id, yaml);
+ return result;
+ }
+
+ @Override
+ public CloudifyBlueprintList uploadBlueprint(CloudifyBlueprintUpload blueprint) {
+ String url = buildUrl(new String[] { baseUrl, blueprintsPath }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "uploadBlueprint: url {}", url);
+ CloudifyBlueprintList result = restTemplate.postForObject(url, blueprint, CloudifyBlueprintList.class);
+ return result;
+ }
+
+ @Override
+ public int deleteBlueprint(final String id) {
+ String url = buildUrl(new String[] { baseUrl, blueprintsPath, id }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "deleteBlueprint: url {}", url);
+ ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, null,
+ new ParameterizedTypeReference<String>() {
+ });
+ return response.getStatusCode().value();
+ }
+
+ @Override
+ public CloudifyDeploymentList getDeployments() {
+ String url = buildUrl(new String[] { baseUrl, deploymentsPath }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "getDeployments: url {}", url);
+ ResponseEntity<CloudifyDeploymentList> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<CloudifyDeploymentList>() {
+ });
+ CloudifyDeploymentList list = response.getBody();
+ return list;
+ }
+
+ @Override
+ public CloudifyDeploymentList getDeployment(final String id) {
+ String url = buildUrl(new String[] { baseUrl, deploymentsPath }, new String[] { "id", id });
+ logger.debug(EELFLoggerDelegate.debugLogger, "getDeployment: url {}", url);
+ ResponseEntity<CloudifyDeploymentList> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<CloudifyDeploymentList>() {
+ });
+ CloudifyDeploymentList list = response.getBody();
+ return list;
+ }
+
+ @Override
+ public CloudifyDeploymentList createDeployment(CloudifyDeploymentRequest deployment) {
+ String url = buildUrl(new String[] { baseUrl, deploymentsPath }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "createDeployment: url {}", url);
+ CloudifyDeploymentList result = restTemplate.postForObject(url, deployment, CloudifyDeploymentList.class);
+ return result;
+ }
+
+ @Override
+ public int deleteDeployment(final String id, boolean ignoreLiveNodes) {
+ String url = buildUrl(new String[] { baseUrl, deploymentsPath, id },
+ new String[] { "ignore_live_nodes", Boolean.toString(ignoreLiveNodes) });
+ logger.debug(EELFLoggerDelegate.debugLogger, "deleteDeployment: url {}", url);
+ ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, null,
+ new ParameterizedTypeReference<String>() {
+ });
+ return response.getStatusCode().value();
+ }
+
+ @Override
+ public CloudifyExecutionList getExecutions(final String deploymentId) {
+ String url = buildUrl(new String[] { baseUrl, executionsPath }, new String[] { "deployment_id", deploymentId });
+ logger.debug(EELFLoggerDelegate.debugLogger, "getExecutions: url {}", url);
+ ResponseEntity<CloudifyExecutionList> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<CloudifyExecutionList>() {
+ });
+ CloudifyExecutionList list = response.getBody();
+ return list;
+ }
+
+ @Override
+ public CloudifyExecutionList getExecution(String executionId, String deploymentId) {
+ String url = buildUrl(new String[] { baseUrl, executionsPath, executionId },
+ new String[] { "deployment_id", deploymentId });
+ logger.debug(EELFLoggerDelegate.debugLogger, "getExecution: url {}", url);
+ ResponseEntity<CloudifyExecutionList> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<CloudifyExecutionList>() {
+ });
+ CloudifyExecutionList list = response.getBody();
+ return list;
+ }
+
+ @Override
+ public CloudifyExecution startExecution(CloudifyExecutionRequest execution) {
+ String url = buildUrl(new String[] { baseUrl, executionsPath }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "startExecution: url {}", url);
+ CloudifyExecution result = restTemplate.postForObject(url, execution, CloudifyExecution.class);
+ return result;
+ }
+
+ @Override
+ public int cancelExecution(final String executionId, final String deploymentId, final String action) {
+ String url = buildUrl(new String[] { baseUrl, executionsPath, executionId },
+ new String[] { "deployment_id", deploymentId, "action", action });
+ logger.debug(EELFLoggerDelegate.debugLogger, "deleteExecution: url {}", url);
+ ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, null,
+ new ParameterizedTypeReference<String>() {
+ });
+ return response.getStatusCode().value();
+ }
+
+ @Override
+ public URI registerService(ConsulHealthServiceRegistration registration) {
+ String url = buildUrl(new String[] { baseUrl, healthServicesPath, "register" }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "registerService: url {}", url);
+ URI uri = restTemplate.postForLocation(url, registration);
+ return uri;
+ }
+
+ @Override
+ public int deregisterService(String serviceName) {
+ String url = buildUrl(new String[] { baseUrl, healthServicesPath, "deregister" , serviceName}, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "deregisterService: url {}", url);
+ ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, null,
+ new ParameterizedTypeReference<String>() {
+ });
+ return response.getStatusCode().value();
+ }
+
+ /**
+ * Translates the awkward map of String-to-List of IP into a list of
+ * ConsulServiceInfo objects
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<ConsulServiceInfo> getServices() {
+ String url = buildUrl(new String[] { baseUrl, healthServicesPath, "services" }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "getServicesHealth: url {}", url);
+ ResponseEntity<Map<String, Object>> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<Map<String, Object>>() {
+ });
+ Map<String, Object> serviceInfo = response.getBody();
+ List<ConsulServiceInfo> list = new ArrayList<>();
+ for (Map.Entry<String, Object> entry : serviceInfo.entrySet()) {
+ // Be defensive
+ List<String> addrs = null;
+ if (entry.getValue() instanceof List<?>)
+ addrs = (List<String>) entry.getValue();
+ else
+ addrs = new ArrayList<>();
+ list.add(new ConsulServiceInfo(entry.getKey(), addrs));
+ }
+ return list;
+ }
+
+ @Override
+ public List<ConsulServiceHealth> getServiceHealth(String serviceName) {
+ String url = buildUrl(new String[] { baseUrl, healthServicesPath, "services", serviceName }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "getServiceHealth: url {}", url);
+ ResponseEntity<List<ConsulServiceHealth>> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<List<ConsulServiceHealth>>() {
+ });
+ List<ConsulServiceHealth> list = response.getBody();
+ return list;
+ }
+
+ @Override
+ public List<ConsulServiceHealthHistory> getServiceHealthHistory(String serviceName, Instant start,
+ Instant end) {
+ String url = buildUrl(new String[] { baseUrl, healthServicesPath, "svchist", serviceName },
+ new String[] { "start", start.toString(), "end", end.toString() });
+ logger.debug(EELFLoggerDelegate.debugLogger, "getServiceHealthHistory: url {}", url);
+ // Hack around an odd interface that returns non-JSON on error:
+ // "No health Data found for the selected dates or service"
+ ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<String>() { });
+ if (response.getBody().startsWith("No health"))
+ throw new RuntimeException(response.getBody());
+ List<ConsulServiceHealthHistory> result = null;
+ try {
+ TypeReference<List<ConsulServiceHealthHistory>> typeRef = new TypeReference<List<ConsulServiceHealthHistory>>() { };
+ result = objectMapper.readValue(response.getBody(), typeRef);
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "getServiceHealthHistory failed to parse response body", ex);
+ }
+ return result;
+ }
+
+ @Override
+ public List<ConsulNodeInfo> getNodes() {
+ String url = buildUrl(new String[] { baseUrl, healthServicesPath, "nodes" }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "getNodesHealth: url {}", url);
+ ResponseEntity<List<ConsulNodeInfo>> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<List<ConsulNodeInfo>>() {
+ });
+ List<ConsulNodeInfo> list = response.getBody();
+ return list;
+ }
+
+ @Override
+ public List<ConsulServiceHealth> getNodeServicesHealth(String nodeId) {
+ String url = buildUrl(new String[] { baseUrl, healthServicesPath, "nodes", nodeId }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "getNodeServicesHealth: url {}", url);
+ ResponseEntity<List<ConsulServiceHealth>> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<List<ConsulServiceHealth>>() {
+ });
+ List<ConsulServiceHealth> list = response.getBody();
+ return list;
+ }
+
+ @Override
+ public List<ConsulDatacenter> getDatacenters() {
+ String url = buildUrl(new String[] { baseUrl, healthServicesPath, "datacenters" }, null);
+ logger.debug(EELFLoggerDelegate.debugLogger, "getDatacentersHealth: url {}", url);
+ ResponseEntity<List<String>> response = restTemplate.exchange(url, HttpMethod.GET, null,
+ new ParameterizedTypeReference<List<String>>() {
+ });
+ List<String> list = response.getBody();
+ List<ConsulDatacenter> result = new ArrayList<>();
+ for (String dc : list)
+ result.add(new ConsulDatacenter(dc));
+ return result;
+ }
+
+ /**
+ * Simple test
+ *
+ * @param args
+ * blueprint ID
+ * @throws Exception
+ * On any failure
+ */
+ public static void main(String[] args) throws Exception {
+ if (args.length != 1)
+ throw new IllegalArgumentException("Single argument expected: blueprint-id");
+ ControllerRestClientImpl client = new ControllerRestClientImpl("http://localhost:8081/controller", "dbus_user",
+ "dbus_pass");
+ final String id = args[0];
+ System.out.println("Requesting blueprint for " + id);
+ CloudifyBlueprintList list = client.getBlueprint(id);
+ if (list == null)
+ System.err.println("Received null");
+ else
+ for (int i = 0; i < list.items.size(); ++i) {
+ System.out.println("Blueprint " + Integer.toString(i));
+ System.out.println(list.items.get(i).toString());
+ }
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientMockImpl.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientMockImpl.java
new file mode 100644
index 0000000..bd855ea
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientMockImpl.java
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.rest;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+
+import org.onap.oom.dashboard.model.CloudifyBlueprintContent;
+import org.onap.oom.dashboard.model.CloudifyBlueprintList;
+import org.onap.oom.dashboard.model.CloudifyBlueprintUpload;
+import org.onap.oom.dashboard.model.CloudifyDeploymentList;
+import org.onap.oom.dashboard.model.CloudifyDeploymentRequest;
+import org.onap.oom.dashboard.model.CloudifyExecution;
+import org.onap.oom.dashboard.model.CloudifyExecutionList;
+import org.onap.oom.dashboard.model.CloudifyExecutionRequest;
+import org.onap.oom.dashboard.model.ConsulDatacenter;
+import org.onap.oom.dashboard.model.ConsulHealthServiceRegistration;
+import org.onap.oom.dashboard.model.ConsulNodeInfo;
+import org.onap.oom.dashboard.model.ConsulServiceHealth;
+import org.onap.oom.dashboard.model.ConsulServiceHealthHistory;
+import org.onap.oom.dashboard.model.ConsulServiceInfo;
+import org.onap.oom.dashboard.model.ECTransportModel;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Provides mock implementations that return contents of files on the classpath.
+ */
+public class ControllerRestClientMockImpl implements IControllerRestClient {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ControllerRestClientMockImpl.class);
+
+ /**
+ * For mock outputs
+ */
+ private final ObjectMapper objectMapper = new ObjectMapper();
+
+ /**
+ * No-arg constructor
+ */
+ public ControllerRestClientMockImpl() {
+ }
+
+ private String getMockDataContent(final String path) {
+ String result = null;
+ try {
+ InputStream is = getClass().getResourceAsStream(path);
+ if (is == null)
+ throw new Exception("Failed to find resource at path " + path);
+ Scanner scanner = new Scanner(is, "UTF-8");
+ result = scanner.useDelimiter("\\A").next();
+ scanner.close();
+ is.close();
+ } catch (Exception ex) {
+ logger.error("getMockDataContent failed", ex);
+ throw new RuntimeException(ex);
+ }
+ return result;
+ }
+
+ /**
+ * Creates an input stream using the specified path and requests the mapper
+ * create an object of the specified type.
+ *
+ * @param modelClass
+ * Model class
+ * @param path
+ * Path to classpath resource
+ * @return Instance of modelClass
+ */
+ private ECTransportModel getMockData(final Class<? extends ECTransportModel> modelClass, final String path) {
+ ECTransportModel result = null;
+ String json = getMockDataContent(path);
+ try {
+ result = (ECTransportModel) objectMapper.readValue(json, modelClass);
+ } catch (Exception ex) {
+ logger.error("getMockData failed", ex);
+ throw new RuntimeException(ex);
+ }
+ return result;
+ }
+
+ @Override
+ public CloudifyBlueprintList getBlueprints() {
+ return (CloudifyBlueprintList) getMockData(CloudifyBlueprintList.class, "/blueprintList.json");
+ }
+
+ @Override
+ public CloudifyBlueprintList getBlueprint(final String id) {
+ return (CloudifyBlueprintList) getMockData(CloudifyBlueprintList.class, "/blueprintByID.json");
+ }
+
+ @Override
+ public CloudifyBlueprintContent viewBlueprint(final String id) {
+ String yaml = getMockDataContent("/blueprintContent.yaml");
+ CloudifyBlueprintContent cbc = new CloudifyBlueprintContent(id, yaml);
+ return cbc;
+ }
+
+ @Override
+ public CloudifyBlueprintList uploadBlueprint(CloudifyBlueprintUpload blueprint) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "uploadBlueprint: {}", blueprint.toString());
+ return new CloudifyBlueprintList(null, null);
+ }
+
+ @Override
+ public int deleteBlueprint(final String id) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "deleteBlueprint: {}", id);
+ return 204;
+ }
+
+ @Override
+ public CloudifyDeploymentList getDeployments() {
+ return (CloudifyDeploymentList) getMockData(CloudifyDeploymentList.class, "/deploymentList.json");
+ }
+
+ @Override
+ public CloudifyDeploymentList getDeployment(final String id) {
+ return (CloudifyDeploymentList) getMockData(CloudifyDeploymentList.class, "/deploymentByID.json");
+ }
+
+ public CloudifyDeploymentList createDeployment(CloudifyDeploymentRequest deployment) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "createDeployment: {}", deployment.toString());
+ return new CloudifyDeploymentList(null, null);
+ }
+
+ @Override
+ public int deleteDeployment(final String id, boolean ignoreLiveNodes) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "deleteDeployment: id {}, ignoreLiveNodes", id, ignoreLiveNodes);
+ return 204;
+ }
+
+ @Override
+ public CloudifyExecutionList getExecutions(final String deploymentId) {
+ return (CloudifyExecutionList) getMockData(CloudifyExecutionList.class, "/listExecutionForDeploymentID.json");
+ }
+
+ @Override
+ public CloudifyExecutionList getExecution(String executionId, String deploymentId) {
+ return (CloudifyExecutionList) getMockData(CloudifyExecutionList.class, "/listExecutionForDeploymentID.json");
+ }
+
+ @Override
+ public CloudifyExecution startExecution(CloudifyExecutionRequest execution) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "startExecution: {}", execution.toString());
+ return new CloudifyExecution(null, null, null, null, null, null, null, null, null);
+ }
+
+ @Override
+ public int cancelExecution(String executionId, String deploymentId, String action) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "deleteExecution: executionId {}, deploymentId {}, action {}",
+ executionId, deploymentId, action);
+ return 204;
+ }
+
+ @Override
+ public URI registerService(ConsulHealthServiceRegistration registration) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "registerService: {}", registration);
+ return null;
+ }
+
+ @Override
+ public int deregisterService(String serviceName) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "deregisterService: {}", serviceName);
+ return 200;
+ }
+
+ @Override
+ public List<ConsulServiceHealth> getServiceHealth(String serviceName) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "getServiceHealth: serviceName={}", serviceName);
+ String json = getMockDataContent("/serviceHealth.json");
+ TypeReference<List<ConsulServiceHealth>> typeRef = new TypeReference<List<ConsulServiceHealth>>() {
+ };
+ List<ConsulServiceHealth> result = null;
+ try {
+ result = objectMapper.readValue(json, typeRef);
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "getServiceHealth failed", ex);
+ }
+ return result;
+ }
+
+ @Override
+ public List<ConsulServiceHealthHistory> getServiceHealthHistory(String serviceName, Instant start, Instant end) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "getServiceHealthHistory: serviceName={}", serviceName);
+ String json = getMockDataContent("/serviceHealthHistory.json");
+ TypeReference<List<ConsulServiceHealthHistory>> typeRef = new TypeReference<List<ConsulServiceHealthHistory>>() {
+ };
+ List<ConsulServiceHealthHistory> result = null;
+ try {
+ result = objectMapper.readValue(json, typeRef);
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "getServiceHealthHistory failed", ex);
+ }
+ return result;
+ }
+
+ @Override
+ public List<ConsulServiceHealth> getNodeServicesHealth(String nodeId) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "getNodeServicesHealth: nodeId={}", nodeId);
+ String json = getMockDataContent("/nodeServicesHealth.json");
+ TypeReference<List<ConsulServiceHealth>> typeRef = new TypeReference<List<ConsulServiceHealth>>() {
+ };
+ List<ConsulServiceHealth> result = null;
+ try {
+ result = objectMapper.readValue(json, typeRef);
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "getNodeServicesHealth failed", ex);
+ }
+ return result;
+ }
+
+ @Override
+ public List<ConsulServiceInfo> getServices() {
+ logger.debug(EELFLoggerDelegate.debugLogger, "getServices");
+ String json = getMockDataContent("/services.json");
+ TypeReference<HashMap<String, Object>> typeRef = new TypeReference<HashMap<String, Object>>() {
+ };
+ HashMap<String, Object> map = null;
+ try {
+ map = objectMapper.readValue(json, typeRef);
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "getNode failed", ex);
+ }
+ ArrayList<ConsulServiceInfo> result = new ArrayList<>();
+ for (Map.Entry<String, Object> entry : map.entrySet()) {
+ final String service = entry.getKey();
+ @SuppressWarnings("unchecked")
+ final List<String> addrs = (List<String>) entry.getValue();
+ result.add(new ConsulServiceInfo(service, addrs));
+ }
+ return result;
+ }
+
+ @Override
+ public List<ConsulNodeInfo> getNodes() {
+ logger.debug(EELFLoggerDelegate.debugLogger, "getNodes");
+ String json = getMockDataContent("/nodesHealth.json");
+ TypeReference<List<ConsulNodeInfo>> typeRef = new TypeReference<List<ConsulNodeInfo>>() {
+ };
+ List<ConsulNodeInfo> result = null;
+ try {
+ result = objectMapper.readValue(json, typeRef);
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "getNode failed", ex);
+
+ }
+ return result;
+ }
+
+ @Override
+ public List<ConsulDatacenter> getDatacenters() {
+ logger.debug(EELFLoggerDelegate.debugLogger, "getDatacentersHealth");
+ return null;
+ }
+
+ /**
+ * Simple test
+ *
+ * @param args
+ * blueprint ID
+ * @throws Exception
+ * On any failure
+ */
+ public static void main(String[] args) throws Exception {
+ System.out.println("Testing paths and parsing mock data");
+ ControllerRestClientMockImpl client = new ControllerRestClientMockImpl();
+ CloudifyBlueprintList list1 = client.getBlueprints();
+ CloudifyBlueprintList list2 = client.getBlueprint("mock");
+ CloudifyDeploymentList list3 = client.getDeployments();
+ CloudifyDeploymentList list4 = client.getDeployment("mock");
+ CloudifyExecutionList list5 = client.getExecutions("mock");
+ List<ConsulServiceInfo> list6 = client.getServices();
+ List<ConsulNodeInfo> list7 = client.getNodes();
+ List<ConsulServiceHealth> list8 = client.getServiceHealth("mock");
+ List<ConsulServiceHealthHistory> list9 = client.getServiceHealthHistory("mock", Instant.now(), Instant.now());
+ if (list1 == null || list2 == null || list3 == null || list4 == null || list5 == null || list6 == null
+ || list7 == null || list8 == null || list9 == null)
+ throw new Exception("Failed");
+ System.out.println("Pass.");
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/HttpComponentsClientHttpRequestFactoryBasicAuth.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/HttpComponentsClientHttpRequestFactoryBasicAuth.java
new file mode 100644
index 0000000..7ad1d46
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/HttpComponentsClientHttpRequestFactoryBasicAuth.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.rest;
+
+import java.net.URI;
+
+import org.apache.http.HttpHost;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+
+/**
+ * Utility class to enable Basic HTTP Authentication with Spring REST templates.
+ *
+ * From:
+ * http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/
+ */
+public class HttpComponentsClientHttpRequestFactoryBasicAuth extends HttpComponentsClientHttpRequestFactory {
+
+ private HttpHost host;
+
+ /**
+ * @param host
+ * HttpHost
+ */
+ public HttpComponentsClientHttpRequestFactoryBasicAuth(HttpHost host) {
+ super();
+ this.host = host;
+ }
+
+ protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
+ return createHttpContext();
+ }
+
+ private HttpContext createHttpContext() {
+ // Create AuthCache instance
+ AuthCache authCache = new BasicAuthCache();
+ // Generate BASIC scheme object and add it to the local auth cache
+ BasicScheme basicAuth = new BasicScheme();
+ authCache.put(host, basicAuth);
+
+ // Add AuthCache to the execution context
+ BasicHttpContext localcontext = new BasicHttpContext();
+ localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache);
+ return localcontext;
+ }
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/IControllerRestClient.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/IControllerRestClient.java
new file mode 100644
index 0000000..a9b1a2d
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/rest/IControllerRestClient.java
@@ -0,0 +1,248 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.rest;
+
+import java.net.URI;
+import java.time.Instant;
+import java.util.List;
+
+import org.onap.oom.dashboard.model.CloudifyBlueprintContent;
+import org.onap.oom.dashboard.model.CloudifyBlueprintList;
+import org.onap.oom.dashboard.model.CloudifyBlueprintUpload;
+import org.onap.oom.dashboard.model.CloudifyDeploymentList;
+import org.onap.oom.dashboard.model.CloudifyDeploymentRequest;
+import org.onap.oom.dashboard.model.CloudifyExecution;
+import org.onap.oom.dashboard.model.CloudifyExecutionList;
+import org.onap.oom.dashboard.model.CloudifyExecutionRequest;
+import org.onap.oom.dashboard.model.ConsulDatacenter;
+import org.onap.oom.dashboard.model.ConsulHealthServiceRegistration;
+import org.onap.oom.dashboard.model.ConsulNodeInfo;
+import org.onap.oom.dashboard.model.ConsulServiceHealth;
+import org.onap.oom.dashboard.model.ConsulServiceHealthHistory;
+import org.onap.oom.dashboard.model.ConsulServiceInfo;
+
+/**
+ * Defines the interface of the Controller REST client.
+ */
+public interface IControllerRestClient {
+
+ public static String blueprintsPath = "blueprints";
+ public static String viewBlueprintsPath = "viewblueprints";
+ public static String deploymentsPath = "deployments";
+ public static String executionsPath = "executions";
+ public static String healthServicesPath = "healthservices";
+
+ /**
+ * Gets the list of Cloudify blueprints.
+ *
+ * @return CloudifyBlueprintList
+ */
+ public CloudifyBlueprintList getBlueprints();
+
+ /**
+ * Gets the Cloudify blueprint metadata for the specified ID
+ *
+ * @param id
+ * Blueprint ID
+ * @return CloudifyBlueprintList of size 1; null if not found
+ */
+ public CloudifyBlueprintList getBlueprint(String id);
+
+ /**
+ * Gets the Cloudify blueprint content for the specified ID
+ *
+ * @param id
+ * Blueprint ID
+ * @return Blueprint content
+ */
+ public CloudifyBlueprintContent viewBlueprint(String id);
+
+ /**
+ * Uploads a Cloudify blueprint.
+ *
+ * @param blueprint
+ * Cloudify Blueprint to upload
+ * @return CloudifyBlueprintList of size 1; null if not found
+ */
+ public CloudifyBlueprintList uploadBlueprint(CloudifyBlueprintUpload blueprint);
+
+ /**
+ * Deletes the Cloudify blueprint with the specified id.
+ *
+ * @param id
+ * Blueprint ID
+ * @return Status code; e.g., 200, 202, 204.
+ */
+ public int deleteBlueprint(String id);
+
+ /**
+ * Gets the list of Cloudify deployments.
+ *
+ * @return CloudifyDeploymentList
+ */
+ public CloudifyDeploymentList getDeployments();
+
+ /**
+ * Gets the Cloudify deployment for the specified ID
+ *
+ * @param id
+ * Deployment ID
+ * @return CloudifyDeploymentList of size 1; null if not found.
+ */
+ public CloudifyDeploymentList getDeployment(String id);
+
+ /**
+ * Creates a Cloudify deployment.
+ *
+ * @param deployment
+ * Deployment details
+ * @return CloudifyDeploymentList of size 1
+ */
+ public CloudifyDeploymentList createDeployment(CloudifyDeploymentRequest deployment);
+
+ /**
+ * Deletes the Cloudify deployment with the specified id.
+ *
+ * @param id
+ * Deployment ID
+ * @param ignoreLiveNodes
+ * Boolean indicator whether to delete even if live nodes exist
+ * @return Status code; e.g., 200, 202, 204.
+ */
+ public int deleteDeployment(String id, boolean ignoreLiveNodes);
+
+ /**
+ * Gets the Cloudify executions for the specified deployment ID
+ *
+ * @param deploymentId
+ * Deployment ID
+ * @return CloudifyExecutionList
+ */
+ public CloudifyExecutionList getExecutions(String deploymentId);
+
+ /**
+ * Gets the Cloudify execution for the specified execution ID and deployment
+ * ID
+ *
+ * @param executionId
+ * Execution ID
+ * @param deploymentId
+ * Deployment ID
+ * @return CloudifyExecutionList of size 1
+ */
+ public CloudifyExecutionList getExecution(String executionId, String deploymentId);
+
+ /**
+ * Starts a Cloudify execution.
+ *
+ * @param execution
+ * Execution details
+ * @return CloudifyExecution
+ */
+ public CloudifyExecution startExecution(CloudifyExecutionRequest execution);
+
+ /**
+ * Deletes the Cloudify execution with the specified ids.
+ *
+ * @param executionId
+ * execution ID
+ * @param deploymentId
+ * Deployment ID
+ * @param action
+ * either "cancel" or "force-cancel"
+ * @return Status code; e.g., 200, 202, 204.
+ */
+ public int cancelExecution(String executionId, String deploymentId, String action);
+
+ /**
+ * Registers a service with Consul for health check.
+ *
+ * @param registration
+ * Details about the service to be registered.
+ * @return Result of registering a service
+ */
+ public URI registerService(ConsulHealthServiceRegistration registration);
+
+ /**
+ * Deregisters a service with Consul for health check.
+ *
+ * @param serviceName
+ * Name of the service to be deregistered.
+ * @return Response code
+ */
+ public int deregisterService(String serviceName);
+
+ /**
+ * Gets all the services that are monitored by Consul.
+ *
+ * @return List of ConsulServiceHealth
+ */
+ public List<ConsulServiceInfo> getServices();
+
+ /**
+ * Gets the status for the specified service on all nodes.
+ *
+ * @param serviceName
+ * Service name
+ * @return List of ConsulServiceHealth
+ */
+ public List<ConsulServiceHealth> getServiceHealth(String serviceName);
+
+ /**
+ * Gets the status for the specified service on all nodes for the specified
+ * time window.
+ *
+ * @param serviceName
+ * Service name
+ * @param start
+ * Start (earliest point) of the time window
+ * @param end
+ * End (latest point) of the time window
+ * @return List of ConsulServiceHealth
+ */
+ public List<ConsulServiceHealthHistory> getServiceHealthHistory(String serviceName, Instant start, Instant end);
+
+ /**
+ * Gets all the nodes that are monitored by Consul.
+ *
+ * @return List of ConsulNodeHealth
+ */
+ public List<ConsulNodeInfo> getNodes();
+
+ /**
+ * Gets the status for all registered services running on the specified
+ * node.
+ *
+ * @param nodeId
+ * Node ID
+ * @return List of ConsulServiceHealth
+ */
+ public List<ConsulServiceHealth> getNodeServicesHealth(String nodeId);
+
+ /**
+ * Gets all the data centers that are monitored by Consul.
+ *
+ * @return List of ConsulDatacenter objects
+ */
+ public List<ConsulDatacenter> getDatacenters();
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/service/ControllerEndpointService.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/service/ControllerEndpointService.java
new file mode 100644
index 0000000..5cec49d
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/service/ControllerEndpointService.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.service;
+
+import org.onap.oom.dashboard.domain.ControllerEndpoint;
+
+/**
+ * Provides methods for managing the user's selection of controller endpoint.
+ *
+ * No method throws a checked exception, in keeping with the Spring philosophy
+ * of throwing unchecked exceptions.
+ */
+public interface ControllerEndpointService {
+
+ /**
+ * Gets the object for the specified user ID.
+ *
+ * @param userId
+ * Application user ID
+ * @return ControllerEndpointCredentials instance; null if none exists.
+ */
+ ControllerEndpoint getControllerEndpointSelection(long userId);
+
+ /**
+ * Creates or updates an entry for the user ID specified within the object.
+ *
+ * @param endpoint
+ * info to store.
+ */
+ void updateControllerEndpointSelection(ControllerEndpoint endpoint);
+
+ /**
+ * Deletes the object for the specified user ID.
+ *
+ * @param userId
+ * Application user ID
+ */
+ void deleteControllerEndpointSelection(long userId);
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/service/ControllerEndpointServiceImpl.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/service/ControllerEndpointServiceImpl.java
new file mode 100644
index 0000000..6b657e1
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/service/ControllerEndpointServiceImpl.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.service;
+
+import org.onap.oom.dashboard.domain.ControllerEndpoint;
+import org.openecomp.portalsdk.core.service.DataAccessService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Complete controller endpoint information is in properties. The database just
+ * stores the user's selection. Users are not expected to enter credentials so
+ * this hybrid solution keeps credentials out of the database.
+ */
+@Service("controllerEndpointService")
+@Transactional
+public class ControllerEndpointServiceImpl implements ControllerEndpointService {
+
+ @Autowired
+ private DataAccessService dataAccessService;
+
+ /**
+ * @return Data access service
+ */
+ public DataAccessService getDataAccessService() {
+ return dataAccessService;
+ }
+
+ /**
+ * @param dataAccessService
+ * Data access service
+ */
+ public void setDataAccessService(DataAccessService dataAccessService) {
+ this.dataAccessService = dataAccessService;
+ }
+
+ @Override
+ public ControllerEndpoint getControllerEndpointSelection(long userId) {
+ return (ControllerEndpoint) getDataAccessService()
+ .getDomainObject(ControllerEndpoint.class, userId, null);
+ }
+
+ @Override
+ public void updateControllerEndpointSelection(ControllerEndpoint endpoint) {
+ getDataAccessService().saveDomainObject(endpoint, null);
+ }
+
+ @Override
+ public void deleteControllerEndpointSelection(long userId) {
+ ControllerEndpoint dbEntry = (ControllerEndpoint) getDataAccessService()
+ .getDomainObject(ControllerEndpoint.class, userId, null);
+ if (dbEntry != null)
+ getDataAccessService().deleteDomainObject(dbEntry, null);
+ }
+
+}
diff --git a/ecd-app-common/src/main/java/org/onap/oom/dashboard/util/DashboardProperties.java b/ecd-app-common/src/main/java/org/onap/oom/dashboard/util/DashboardProperties.java
new file mode 100644
index 0000000..2dbd103
--- /dev/null
+++ b/ecd-app-common/src/main/java/org/onap/oom/dashboard/util/DashboardProperties.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.oom.dashboard.util;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+
+/**
+ * Publishes a list of constants and methods to access the properties that are
+ * read by Spring from the specified configuration file(s).
+ *
+ * Should be used like this (and never in a constructor):
+ *
+ * <pre>
+ * &#64;Autowired
+ * DashboardProperties properties;
+ * </pre>
+ */
+@Configuration
+@PropertySource(value = { "${container.classpath:}/WEB-INF/conf/dashboard.properties" })
+public class DashboardProperties {
+
+ /**
+ * Key for property that indicates if test data should be used
+ */
+ public static final String CONTROLLER_MOCK_DATA = "controller.mock.data";
+ /**
+ * Key for property with list of controllers
+ */
+ public static final String CONTROLLER_KEY_LIST = "controller.key.list";
+ /**
+ * Subkey for property with Controller name (description)
+ */
+ public static final String CONTROLLER_SUBKEY_NAME = "name";
+ /**
+ * Subkey for property with Controller URL
+ */
+ public static final String CONTROLLER_SUBKEY_URL = "url";
+ /**
+ * Subkey for property with Controller user name for authentication
+ */
+ public static final String CONTROLLER_SUBKEY_USERNAME = "username";
+ /**
+ * Subkey for property with Controller password
+ */
+ public static final String CONTROLLER_SUBKEY_PASSWORD = "password";
+ /**
+ * Subkey for property with Controller password encryption status
+ */
+ public static final String CONTROLLER_SUBKEY_ENCRYPTED = "is_encrypted";
+
+ private Environment environment;
+
+ /**
+ * No-arg constructor
+ */
+ public DashboardProperties() {
+ }
+
+ protected Environment getEnvironment() {
+ return environment;
+ }
+
+ /**
+ * @param environment
+ * Environment
+ */
+ @Autowired
+ public void setEnvironment(final Environment environment) {
+ this.environment = environment;
+ }
+
+ /**
+ * @param key
+ * Property key
+ * @return True or false
+ */
+ public boolean containsProperty(final String key) {
+ return environment.containsProperty(key);
+ }
+
+ /**
+ * @param key
+ * Property key
+ * @return String value; throws unchecked exception if key is not found
+ */
+ public String getProperty(final String key) {
+ return environment.getRequiredProperty(key);
+ }
+
+ /**
+ * @param key
+ * Property key
+ * @return True or False; null if key is not found
+ */
+ public Boolean getBooleanProperty(final String key) {
+ final String value = getProperty(key);
+ return Boolean.parseBoolean(value);
+ }
+
+ /**
+ * Gets the values for a comma-separated list property value as a String
+ * array.
+ *
+ * @param key
+ * Property key
+ * @return Array of values with leading and trailing whitespace removed;
+ * null if key is not found.
+ */
+ public String[] getCsvListProperty(final String key) {
+ String listVal = getProperty(key);
+ if (listVal == null)
+ return null;
+ String[] vals = listVal.split("\\s*,\\s*");
+ return vals;
+ }
+
+ /**
+ * Convenience method to get a property from the fake hierarchical key-value
+ * set.
+ *
+ * @param controllerKey
+ * First part of key
+ * @param propKey
+ * Second part of key
+ * @return Property value for key "controllerKey.propKey"
+ */
+ public String getControllerProperty(final String controllerKey, final String propKey) {
+ final String key = controllerKey + '.' + propKey;
+ return getProperty(key);
+ }
+
+}
diff --git a/ecd-app-common/src/test/java/org/onap/fusion/core/MockApplicationContextTestSuite.java b/ecd-app-common/src/test/java/org/onap/fusion/core/MockApplicationContextTestSuite.java
new file mode 100644
index 0000000..f3d55e2
--- /dev/null
+++ b/ecd-app-common/src/test/java/org/onap/fusion/core/MockApplicationContextTestSuite.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.fusion.core;
+
+import java.io.IOException;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.openecomp.portalsdk.core.conf.AppConfig;
+import org.openecomp.portalsdk.core.objectcache.AbstractCacheManager;
+import org.openecomp.portalsdk.core.util.CacheManager;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.AnnotationConfigWebContextLoader;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+
+/**
+ * In order to write a unit test, 1. inherit this class - See SanityTest.java 2.
+ * place the "war" folder on your test class's classpath 3. run the test with
+ * the following VM argument; This is important because when starting the
+ * application from Container, the System Properties file
+ * (SystemProperties.java) can have the direct path but, when running from the
+ * Mock Junit container, the path should be prefixed with "classpath" to enable
+ * the mock container to search for the file in the classpath
+ * -Dcontainer.classpath="classpath:"
+ *
+ */
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+@ContextConfiguration(loader = AnnotationConfigWebContextLoader.class, classes = { MockAppConfig.class })
+@ActiveProfiles(value = "test")
+public class MockApplicationContextTestSuite {
+
+ @Autowired
+ public WebApplicationContext wac;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setup() {
+ if (mockMvc == null) {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
+
+ }
+ }
+
+ public Object getBean(String name) {
+ return this.wac.getBean(name);
+ }
+
+ public MockMvc getMockMvc() {
+ return mockMvc;
+ }
+
+ public void setMockMvc(MockMvc mockMvc) {
+ this.mockMvc = mockMvc;
+ }
+
+ public WebApplicationContext getWebApplicationContext() {
+ return wac;
+ }
+
+}
+
+@Configuration
+@ComponentScan(basePackages = {"org.openecomp", "org.onap"}, excludeFilters = {
+ // see AppConfig class
+})
+@Profile("test")
+class MockAppConfig extends AppConfig {
+
+ @Bean
+ public SystemProperties systemProperties() {
+ return new MockSystemProperties();
+ }
+
+ @Bean
+ public AbstractCacheManager cacheManager() {
+ return new CacheManager() {
+
+ public void configure() throws IOException {
+
+ }
+ };
+ }
+
+ protected String[] tileDefinitions() {
+ return new String[] { "classpath:/WEB-INF/fusion/defs/definitions.xml",
+ "classpath:/WEB-INF/defs/definitions.xml" };
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ // registry.addInterceptor(new
+ // SessionTimeoutInterceptor()).excludePathPatterns(getExcludeUrlPathsForSessionTimeout());
+ // registry.addInterceptor(resourceInterceptor());
+ }
+
+ public static class MockSystemProperties extends SystemProperties {
+
+ public MockSystemProperties() {
+ }
+
+ }
+
+}
diff --git a/ecd-app-common/src/test/java/org/onap/fusionapp/SanityTest.java b/ecd-app-common/src/test/java/org/onap/fusionapp/SanityTest.java
new file mode 100644
index 0000000..c859c28
--- /dev/null
+++ b/ecd-app-common/src/test/java/org/onap/fusionapp/SanityTest.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.fusionapp;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.fusion.core.MockApplicationContextTestSuite;
+import org.springframework.test.web.servlet.ResultActions;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+
+public class SanityTest extends MockApplicationContextTestSuite {
+
+ @Test
+ public void testGetAvailableRoles() throws Exception {
+
+ ResultActions ra =getMockMvc().perform(MockMvcRequestBuilders.get("/api/roles"));
+ //Assert.assertEquals(UrlAccessRestrictedException.class,ra.andReturn().getResolvedException().getClass());
+ Assert.assertEquals("application/json",ra.andReturn().getResponse().getContentType());
+ }
+
+
+}
diff --git a/ecd-app-common/src/test/java/org/onap/fusionapp/service/ProfileServiceTest.java b/ecd-app-common/src/test/java/org/onap/fusionapp/service/ProfileServiceTest.java
new file mode 100644
index 0000000..4a661da
--- /dev/null
+++ b/ecd-app-common/src/test/java/org/onap/fusionapp/service/ProfileServiceTest.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * =============LICENSE_START=========================================================
+ *
+ * =================================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *******************************************************************************/
+package org.onap.fusionapp.service;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.fusion.core.MockApplicationContextTestSuite;
+import org.openecomp.portalsdk.core.domain.Profile;
+import org.openecomp.portalsdk.core.domain.User;
+import org.openecomp.portalsdk.core.service.ProfileService;
+import org.openecomp.portalsdk.core.service.UserProfileService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+public class ProfileServiceTest extends MockApplicationContextTestSuite {
+
+ @Autowired
+ ProfileService service;
+
+ @Autowired
+ UserProfileService userProfileService;
+
+ @Test
+ public void testFindAll() {
+
+ List<Profile> profiles = service.findAll();
+ Assert.assertTrue(profiles.size() > 0);
+ }
+
+ @Test
+ public void testFindAllActive() {
+
+ List<User> users = userProfileService.findAllActive();
+ List<User> activeUsers = userProfileService.findAllActive();
+ Assert.assertTrue(users.size() - activeUsers.size() >= 0);
+ }
+}