diff options
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/migrations/2018-05-12-001226_init/up.sql | 8 | ||||
| -rw-r--r-- | rust/src/api_server.rs | 77 | ||||
| -rw-r--r-- | rust/src/api_wrappers.rs | 38 | ||||
| -rw-r--r-- | rust/tests/test_api_server_http.rs | 152 | 
4 files changed, 240 insertions, 35 deletions
| diff --git a/rust/migrations/2018-05-12-001226_init/up.sql b/rust/migrations/2018-05-12-001226_init/up.sql index b5214078..88614e7b 100644 --- a/rust/migrations/2018-05-12-001226_init/up.sql +++ b/rust/migrations/2018-05-12-001226_init/up.sql @@ -425,10 +425,10 @@ INSERT INTO work_edit (ident_id, rev_id, redirect_id, editgroup_id, prev_rev) VA      ('00000000-0000-0000-5555-000000000002', '00000000-0000-0000-5555-FFF000000002', null, '00000000-0000-0000-BBBB-000000000004', null),      ('00000000-0000-0000-5555-000000000002', '00000000-0000-0000-5555-FFF000000003', null, '00000000-0000-0000-BBBB-000000000005', '00000000-0000-0000-5555-FFF000000002'); -INSERT INTO release_rev (id, work_ident_id, container_ident_id, title, release_type, release_status, release_date, doi, isbn13, core_id, volume, issue, pages, publisher, language) VALUES -    ('00000000-0000-0000-4444-FFF000000001', '00000000-0000-0000-5555-000000000001',                                   null,  'example title',              null, null,        null,         null,            null,       null, null, null,  null,                     null, null), -    ('00000000-0000-0000-4444-FFF000000002', '00000000-0000-0000-5555-000000000002', '00000000-0000-0000-1111-000000000001', 'bigger example', 'article-journal', null,'2018-01-01', '10.123/abc', '978-3-16-148410-0', '42022773', '12', 'IV', '5-9', 'bogus publishing group', 'cn'), -    ('00000000-0000-0000-4444-FFF000000003', '00000000-0000-0000-5555-000000000003', '00000000-0000-0000-1111-000000000003', 'Why Most Published Research Findings Are False', 'article-journal', 'published', '2005-08-30', '10.1371/journal.pmed.0020124',  null, null, '2', '8', 'e124', 'Public Library of Science', 'en'); +INSERT INTO release_rev (id, work_ident_id, container_ident_id, title, release_type, release_status, release_date, doi, wikidata_qid, pmid, pmcid, isbn13, core_id, volume, issue, pages, publisher, language) VALUES +    ('00000000-0000-0000-4444-FFF000000001', '00000000-0000-0000-5555-000000000001',                                   null,                                  'example title',             null,         null,         null,                          null,      null,    null,     null,               null,       null, null, null,  null, null, null), +    ('00000000-0000-0000-4444-FFF000000002', '00000000-0000-0000-5555-000000000002', '00000000-0000-0000-1111-000000000001',                                 'bigger example', 'article-journal',        null, '2018-01-01',                   '10.123/abc', 'Q55555', '54321', 'PMC555','978-3-16-148410-0', '42022773', '12', 'IV', '5-9', 'bogus publishing group', 'cn'), +    ('00000000-0000-0000-4444-FFF000000003', '00000000-0000-0000-5555-000000000003', '00000000-0000-0000-1111-000000000003', 'Why Most Published Research Findings Are False', 'article-journal', 'published', '2005-08-30', '10.1371/journal.pmed.0020124',     null,    null,     null,               null,       null, '2', '8', 'e124', 'Public Library of Science', 'en');  INSERT INTO release_ident (id, is_live, rev_id, redirect_id) VALUES      ('00000000-0000-0000-4444-000000000001', true, '00000000-0000-0000-4444-FFF000000001', null), -- aaaaaaaaaaaaarceaaaaaaaaae diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs index 0a415e91..2278f64f 100644 --- a/rust/src/api_server.rs +++ b/rust/src/api_server.rs @@ -53,7 +53,7 @@ pub struct Server {      pub db_pool: ConnectionPool,  } -pub fn get_release_files(id: FatCatId, hide: HideFlags, conn: &DbConn) -> Result<Vec<FileEntity>> { +pub fn get_release_files(id: FatCatId, hide_flags: HideFlags, conn: &DbConn) -> Result<Vec<FileEntity>> {      let rows: Vec<(FileRevRow, FileIdentRow, FileReleaseRow)> = file_rev::table          .inner_join(file_ident::table)          .inner_join(file_release::table) @@ -63,7 +63,7 @@ pub fn get_release_files(id: FatCatId, hide: HideFlags, conn: &DbConn) -> Result          .load(conn)?;      rows.into_iter() -        .map(|(rev, ident, _)| FileEntity::db_from_row(conn, rev, Some(ident), hide)) +        .map(|(rev, ident, _)| FileEntity::db_from_row(conn, rev, Some(ident), hide_flags))          .collect()  } @@ -72,7 +72,8 @@ impl Server {          &self,          issnl: &Option<String>,          wikidata_qid: &Option<String>, -        hide: HideFlags, +        expand_flags: ExpandFlags, +        hide_flags: HideFlags,          conn: &DbConn,      ) -> Result<ContainerEntity> {          let (ident, rev): (ContainerIdentRow, ContainerRevRow) = match (issnl, wikidata_qid) { @@ -86,7 +87,7 @@ impl Server {                      .first(conn)?              }              (None, Some(wikidata_qid)) => { -                check_issn(wikidata_qid)?; +                check_wikidata_qid(wikidata_qid)?;                  container_ident::table                      .inner_join(container_rev::table)                      .filter(container_rev::wikidata_qid.eq(&wikidata_qid)) @@ -99,14 +100,17 @@ impl Server {              }          }; -        ContainerEntity::db_from_row(conn, rev, Some(ident), hide) +        let mut entity = ContainerEntity::db_from_row(conn, rev, Some(ident), hide_flags)?; +        entity.db_expand(&conn, expand_flags)?; +        Ok(entity)      }      pub fn lookup_creator_handler(          &self,          orcid: &Option<String>,          wikidata_qid: &Option<String>, -        hide: HideFlags, +        expand_flags: ExpandFlags, +        hide_flags: HideFlags,          conn: &DbConn,      ) -> Result<CreatorEntity> {          let (ident, rev): (CreatorIdentRow, CreatorRevRow) = match (orcid, wikidata_qid) { @@ -133,13 +137,15 @@ impl Server {              }          }; -        CreatorEntity::db_from_row(conn, rev, Some(ident), hide) +        let mut entity = CreatorEntity::db_from_row(conn, rev, Some(ident), hide_flags)?; +        entity.db_expand(&conn, expand_flags)?; +        Ok(entity)      }      pub fn get_creator_releases_handler(          &self,          id: FatCatId, -        hide: HideFlags, +        hide_flags: HideFlags,          conn: &DbConn,      ) -> Result<Vec<ReleaseEntity>> {          // TODO: some kind of unique or group-by? @@ -153,7 +159,7 @@ impl Server {          // TODO: from_rows, not from_row?          rows.into_iter() -            .map(|(rev, ident, _)| ReleaseEntity::db_from_row(conn, rev, Some(ident), hide)) +            .map(|(rev, ident, _)| ReleaseEntity::db_from_row(conn, rev, Some(ident), hide_flags))              .collect()      } @@ -162,7 +168,8 @@ impl Server {          md5: &Option<String>,          sha1: &Option<String>,          sha256: &Option<String>, -        hide: HideFlags, +        expand_flags: ExpandFlags, +        hide_flags: HideFlags,          conn: &DbConn,      ) -> Result<FileEntity> {          let (ident, rev): (FileIdentRow, FileRevRow) = match (md5, sha1, sha256) { @@ -189,7 +196,9 @@ impl Server {              }          }; -        FileEntity::db_from_row(conn, rev, Some(ident), hide) +        let mut entity = FileEntity::db_from_row(conn, rev, Some(ident), hide_flags)?; +        entity.db_expand(&conn, expand_flags)?; +        Ok(entity)      }      pub fn lookup_release_handler( @@ -199,12 +208,14 @@ impl Server {          isbn13: &Option<String>,          pmid: &Option<String>,          pmcid: &Option<String>, -        hide: HideFlags, +        core_id: &Option<String>, +        expand_flags: ExpandFlags, +        hide_flags: HideFlags,          conn: &DbConn,      ) -> Result<ReleaseEntity> {          let (ident, rev): (ReleaseIdentRow, ReleaseRevRow) = -            match (doi, wikidata_qid, isbn13, pmid, pmcid) { -                (Some(doi), None, None, None, None) => { +            match (doi, wikidata_qid, isbn13, pmid, pmcid, core_id) { +                (Some(doi), None, None, None, None, None) => {                      check_doi(doi)?;                      release_ident::table                          .inner_join(release_rev::table) @@ -213,7 +224,7 @@ impl Server {                          .filter(release_ident::redirect_id.is_null())                          .first(conn)?                  } -                (None, Some(wikidata_qid), None, None, None) => { +                (None, Some(wikidata_qid), None, None, None, None) => {                      check_wikidata_qid(wikidata_qid)?;                      release_ident::table                          .inner_join(release_rev::table) @@ -222,7 +233,7 @@ impl Server {                          .filter(release_ident::redirect_id.is_null())                          .first(conn)?                  } -                (None, None, Some(isbn13), None, None) => { +                (None, None, Some(isbn13), None, None, None) => {                      // TODO: check_isbn13(isbn13)?;                      release_ident::table                          .inner_join(release_rev::table) @@ -231,7 +242,7 @@ impl Server {                          .filter(release_ident::redirect_id.is_null())                          .first(conn)?                  } -                (None, None, None, Some(pmid), None) => { +                (None, None, None, Some(pmid), None, None) => {                      check_pmid(pmid)?;                      release_ident::table                          .inner_join(release_rev::table) @@ -240,7 +251,7 @@ impl Server {                          .filter(release_ident::redirect_id.is_null())                          .first(conn)?                  } -                (None, None, None, None, Some(pmcid)) => { +                (None, None, None, None, Some(pmcid), None) => {                      check_pmcid(pmcid)?;                      release_ident::table                          .inner_join(release_rev::table) @@ -249,6 +260,15 @@ impl Server {                          .filter(release_ident::redirect_id.is_null())                          .first(conn)?                  } +                (None, None, None, None, None, Some(core_id)) => { +                    // TODO: check_core_id(core_id)?; +                    release_ident::table +                        .inner_join(release_rev::table) +                        .filter(release_rev::core_id.eq(core_id)) +                        .filter(release_ident::is_live.eq(true)) +                        .filter(release_ident::redirect_id.is_null()) +                        .first(conn)? +                }                  _ => {                      return Err(                          ErrorKind::MissingOrMultipleExternalId("in lookup".to_string()).into(), @@ -256,22 +276,24 @@ impl Server {                  }              }; -        ReleaseEntity::db_from_row(conn, rev, Some(ident), hide) +        let mut entity = ReleaseEntity::db_from_row(conn, rev, Some(ident), hide_flags)?; +        entity.db_expand(&conn, expand_flags)?; +        Ok(entity)      }      pub fn get_release_files_handler(          &self,          id: FatCatId, -        hide: HideFlags, +        hide_flags: HideFlags,          conn: &DbConn,      ) -> Result<Vec<FileEntity>> { -        get_release_files(id, hide, conn) +        get_release_files(id, hide_flags, conn)      }      pub fn get_work_releases_handler(          &self,          id: FatCatId, -        hide: HideFlags, +        hide_flags: HideFlags,          conn: &DbConn,      ) -> Result<Vec<ReleaseEntity>> {          let rows: Vec<(ReleaseRevRow, ReleaseIdentRow)> = release_rev::table @@ -282,7 +304,7 @@ impl Server {              .load(conn)?;          rows.into_iter() -            .map(|(rev, ident)| ReleaseEntity::db_from_row(conn, rev, Some(ident), hide)) +            .map(|(rev, ident)| ReleaseEntity::db_from_row(conn, rev, Some(ident), hide_flags))              .collect()      } @@ -301,7 +323,8 @@ impl Server {                  editgroup::editor_id.eq(FatCatId::from_str(&entity.editor_id)?.to_uuid()),                  editgroup::description.eq(entity.description),                  editgroup::extra_json.eq(entity.extra), -            )).get_result(conn)?; +            )) +            .get_result(conn)?;          Ok(Editgroup {              id: Some(uuid2fcid(&row.id)), @@ -397,7 +420,8 @@ impl Server {                  editgroup: Some(eg_row.into_model_partial()),                  editgroup_id: uuid2fcid(&cl_row.editgroup_id),                  timestamp: chrono::DateTime::from_utc(cl_row.timestamp, chrono::Utc), -            }).collect(); +            }) +            .collect();          Ok(entries)      } @@ -421,7 +445,8 @@ impl Server {                  editgroup: Some(eg_row.into_model_partial()),                  editgroup_id: uuid2fcid(&cl_row.editgroup_id),                  timestamp: chrono::DateTime::from_utc(cl_row.timestamp, chrono::Utc), -            }).collect(); +            }) +            .collect();          Ok(entries)      } diff --git a/rust/src/api_wrappers.rs b/rust/src/api_wrappers.rs index 8c274fb5..cb93ec54 100644 --- a/rust/src/api_wrappers.rs +++ b/rust/src/api_wrappers.rs @@ -371,22 +371,29 @@ macro_rules! wrap_lookup_handler {              &self,              $idname: Option<String>,              wikidata_qid: Option<String>, +            expand: Option<String>,              hide: Option<String>,              _context: &Context,          ) -> Box<Future<Item = $get_resp, Error = ApiError> + Send> {              let conn = self.db_pool.get().expect("db_pool error"); +            let expand_flags = match expand { +                None => ExpandFlags::none(), +                Some(param) => ExpandFlags::from_str(¶m).unwrap(), +            };              let hide_flags = match hide {                  None => HideFlags::none(),                  Some(param) => HideFlags::from_str(¶m).unwrap(),              };              // No transaction for GET -            let ret = match self.$get_handler(&$idname, &wikidata_qid, hide_flags, &conn) { +            let ret = match self.$get_handler(&$idname, &wikidata_qid, expand_flags, hide_flags, &conn) {                  Ok(entity) =>                      $get_resp::FoundEntity(entity),                  Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) =>                      $get_resp::NotFound(ErrorResponse { message: format!("Not found: {:?} / {:?}", $idname, wikidata_qid) }),                  Err(Error(ErrorKind::MalformedExternalId(e), _)) =>                      $get_resp::BadRequest(ErrorResponse { message: e.to_string() }), +                Err(Error(ErrorKind::MissingOrMultipleExternalId(e), _)) => { +                    $get_resp::BadRequest(ErrorResponse { message: e.to_string(), }) },                  Err(e) => {                      error!("{}", e);                      $get_resp::BadRequest(ErrorResponse { message: e.to_string() }) @@ -627,16 +634,21 @@ impl Api for Server {          md5: Option<String>,          sha1: Option<String>,          sha256: Option<String>, +        expand: Option<String>,          hide: Option<String>,          _context: &Context,      ) -> Box<Future<Item = LookupFileResponse, Error = ApiError> + Send> {          let conn = self.db_pool.get().expect("db_pool error"); +        let expand_flags = match expand { +            None => ExpandFlags::none(), +            Some(param) => ExpandFlags::from_str(¶m).unwrap(), +        };          let hide_flags = match hide {              None => HideFlags::none(),              Some(param) => HideFlags::from_str(¶m).unwrap(),          };          // No transaction for GET -        let ret = match self.lookup_file_handler(&md5, &sha1, &sha256, hide_flags, &conn) { +        let ret = match self.lookup_file_handler(&md5, &sha1, &sha256, expand_flags, hide_flags, &conn) {              Ok(entity) => LookupFileResponse::FoundEntity(entity),              Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) => {                  LookupFileResponse::NotFound(ErrorResponse { @@ -648,6 +660,11 @@ impl Api for Server {                      message: e.to_string(),                  })              } +            Err(Error(ErrorKind::MissingOrMultipleExternalId(e), _)) => { +                LookupFileResponse::BadRequest(ErrorResponse { +                    message: e.to_string(), +                }) +            }              Err(e) => {                  error!("{}", e);                  LookupFileResponse::BadRequest(ErrorResponse { @@ -665,10 +682,16 @@ impl Api for Server {          isbn13: Option<String>,          pmid: Option<String>,          pmcid: Option<String>, +        core_id: Option<String>, +        expand: Option<String>,          hide: Option<String>,          _context: &Context,      ) -> Box<Future<Item = LookupReleaseResponse, Error = ApiError> + Send> {          let conn = self.db_pool.get().expect("db_pool error"); +        let expand_flags = match expand { +            None => ExpandFlags::none(), +            Some(param) => ExpandFlags::from_str(¶m).unwrap(), +        };          let hide_flags = match hide {              None => HideFlags::none(),              Some(param) => HideFlags::from_str(¶m).unwrap(), @@ -680,6 +703,8 @@ impl Api for Server {              &isbn13,              &pmid,              &pmcid, +            &core_id, +            expand_flags,              hide_flags,              &conn,          ) { @@ -687,8 +712,8 @@ impl Api for Server {              Err(Error(ErrorKind::Diesel(::diesel::result::Error::NotFound), _)) => {                  LookupReleaseResponse::NotFound(ErrorResponse {                      message: format!( -                        "Not found: {:?} / {:?} / {:?} / {:?} / {:?}", -                        doi, wikidata_qid, isbn13, pmid, pmcid +                        "Not found: {:?} / {:?} / {:?} / {:?} / {:?} / {:?}", +                        doi, wikidata_qid, isbn13, pmid, pmcid, core_id                      ),                  })              } @@ -697,6 +722,11 @@ impl Api for Server {                      message: e.to_string(),                  })              } +            Err(Error(ErrorKind::MissingOrMultipleExternalId(e), _)) => { +                LookupReleaseResponse::BadRequest(ErrorResponse { +                    message: e.to_string(), +                }) +            }              Err(e) => {                  error!("{}", e);                  LookupReleaseResponse::BadRequest(ErrorResponse { diff --git a/rust/tests/test_api_server_http.rs b/rust/tests/test_api_server_http.rs index 614e6b65..031a0abf 100644 --- a/rust/tests/test_api_server_http.rs +++ b/rust/tests/test_api_server_http.rs @@ -197,6 +197,46 @@ fn test_lookups() {      check_http_response(          request::get( +            "http://localhost:9411/v0/container/lookup?issnl=1234", +            headers.clone(), +            &router, +        ), +        status::BadRequest, +        None, +    ); + +    check_http_response( +        request::get( +            "http://localhost:9411/v0/container/lookup?wikidata_qid=Q84913959359", +            headers.clone(), +            &router, +        ), +        status::NotFound, +        None, +    ); + +    check_http_response( +        request::get( +            "http://localhost:9411/v0/container/lookup?wikidata_qid=84913959359", +            headers.clone(), +            &router, +        ), +        status::BadRequest, +        None, +    ); + +    check_http_response( +        request::get( +            "http://localhost:9411/v0/container/lookup?wikidata_qid=Q84913959359&issnl=1234-0000", +            headers.clone(), +            &router, +        ), +        status::BadRequest, +        None, +    ); + +    check_http_response( +        request::get(              "http://localhost:9411/v0/creator/lookup?orcid=0000-0003-2088-7465",              headers.clone(),              &router, @@ -207,6 +247,16 @@ fn test_lookups() {      check_http_response(          request::get( +            "http://localhost:9411/v0/creator/lookup?wikidata_qid=Q5678", +            headers.clone(), +            &router, +        ), +        status::Ok, +        Some("John P. A. Ioannidis"), +    ); + +    check_http_response( +        request::get(              "http://localhost:9411/v0/creator/lookup?orcid=0000-0003-2088-0000",              headers.clone(),              &router, @@ -217,6 +267,24 @@ fn test_lookups() {      check_http_response(          request::get( +            "http://localhost:9411/v0/file/lookup?md5=7d97e98f8af710c7e7fe703abc8f639e0ee507c4", +            headers.clone(), +            &router, +        ), +        status::NotFound, +        None, +    ); +    check_http_response( +        request::get( +            "http://localhost:9411/v0/file/lookup?md5=f4de91152c7ab9fdc2a128f962faebff", +            headers.clone(), +            &router, +        ), +        status::Ok, +        Some("0020124&type=printable"), +    ); +    check_http_response( +        request::get(              "http://localhost:9411/v0/file/lookup?sha1=7d97e98f8af710c7e7fe703abc8f639e0ee507c4",              headers.clone(),              &router, @@ -224,6 +292,15 @@ fn test_lookups() {          status::Ok,          Some("robots.txt"),      ); +    check_http_response( +        request::get( +            "http://localhost:9411/v0/file/lookup?sha256=ffc1005680cb620eec4c913437dfabbf311b535cfe16cbaeb2faec1f92afc362", +            headers.clone(), +            &router, +        ), +        status::Ok, +        Some("0020124&type=printable"), +    );      check_http_response(          request::get( @@ -234,6 +311,78 @@ fn test_lookups() {          status::NotFound,          None,      ); + +    // not URL encoded +    check_http_response( +        request::get( +            "http://localhost:9411/v0/release/lookup?doi=10.123/abc", +            headers.clone(), +            &router, +        ), +        status::Ok, +        Some("bigger example"), +    ); + +    // URL encoded +    check_http_response( +        request::get( +            "http://localhost:9411/v0/release/lookup?doi=10.123%2Fabc", +            headers.clone(), +            &router, +        ), +        status::Ok, +        Some("bigger example"), +    ); + +    check_http_response( +        request::get( +            "http://localhost:9411/v0/release/lookup?wikidata_qid=Q55555", +            headers.clone(), +            &router, +        ), +        status::Ok, +        Some("bigger example"), +    ); + +    check_http_response( +        request::get( +            "http://localhost:9411/v0/release/lookup?pmid=54321", +            headers.clone(), +            &router, +        ), +        status::Ok, +        Some("bigger example"), +    ); + +    check_http_response( +        request::get( +            "http://localhost:9411/v0/release/lookup?pmcid=PMC555", +            headers.clone(), +            &router, +        ), +        status::Ok, +        Some("bigger example"), +    ); + +    check_http_response( +        request::get( +            "http://localhost:9411/v0/release/lookup?isbn13=978-3-16-148410-0", +            headers.clone(), +            &router, +        ), +        status::Ok, +        Some("bigger example"), +    ); + +    check_http_response( +        request::get( +            "http://localhost:9411/v0/release/lookup?core_id=42022773", +            headers.clone(), +            &router, +        ), +        status::Ok, +        Some("bigger example"), +    );  }  #[test] @@ -474,7 +623,8 @@ fn test_post_release() {          status::BadRequest,          None,      ); -    */} +    */ +}  #[test]  fn test_post_work() { | 
