Skip to content

Commit

Permalink
feature: rajapinta projektin hakemiselle Velhosta
Browse files Browse the repository at this point in the history
  • Loading branch information
haapamakim committed Sep 29, 2021
1 parent c87cc04 commit 414d4ab
Show file tree
Hide file tree
Showing 17 changed files with 456 additions and 47 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ out
backend/src/velho/aineistopalvelu
backend/src/velho/hakupalvelu
backend/src/velho/projektirekisteri
backend/src/velho/metadata.json

# Gradle
tools/velho/.gradle
tools/velho/build
!tools/velho/gradle/wrapper/gradle-wrapper.jar
tools/velho/buildSrc/.gradle
tools/velho/buildSrc/build

.report
.nyc_output
Expand Down
6 changes: 4 additions & 2 deletions backend/integrationtest/velho/velhoClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,25 @@ describe("VelhoClient", () => {
expect(searchResult).not.null;
expect(searchResult).not.be.empty;
const firstSearchResult = searchResult[0];
log.info(firstSearchResult);
log.debug(firstSearchResult);
name = firstSearchResult.name;
oid = firstSearchResult.oid;
log.debug("nimi", name);
});

it("should list one exact project from Velho", async () => {
expect(oid).to.not.be.null;
expect(name).to.not.be.null;
const exactSearchResult = await velho.searchProjects(name, true);
expect(exactSearchResult).not.be.empty;
log.debug(exactSearchResult);
expect(exactSearchResult[0].oid).to.be.equal(oid);
});

it("should load project from Velho", async () => {
expect(oid).to.not.be.null;
const searchResult = await velho.loadProject(oid);
expect(searchResult).not.null;
log.info(JSON.stringify(searchResult, null, 2));
log.debug(JSON.stringify(searchResult, null, 2));
});
});
9 changes: 5 additions & 4 deletions backend/src/error/velhoError.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
export class VelhoError extends Error {
constructor(m?: string) {
super(m ? m : "");
constructor(m?: string, error?: any) {
super(m ? m + (error ? JSON.stringify(error.response?.data) : "") : "");

// Set the prototype explicitly.
Object.setPrototypeOf(this, VelhoError.prototype);
// Make the log show VelhoError instead of Error in the stack trace
this.name = new.target.name;
Object.setPrototypeOf(this, new.target.prototype);
}
}
56 changes: 38 additions & 18 deletions backend/src/velho/velhoAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import { VelhoHakuTulos } from "../api/apiModel";
import { ProjektiProjekti } from "./projektirekisteri";
import { Projekti, VelhoHakuTulos } from "../api/apiModel";
import { ProjektiProjekti, ProjektiProjektiOminaisuudetVaylamuotoEnum } from "./projektirekisteri";
// @ts-ignore
import { default as metadataJson } from "./metadata.json";

function adaptVaylamuoto(vaylamuodot: string[]) {
return vaylamuodot
.map((vaylamuoto) => {
switch (vaylamuoto) {
case "tie":
return "Tiesuunnitelma";
case "rata":
return "Ratasuunnitelma";
default:
return vaylamuoto;
}
})
.join(", ");
function extractValuesIntoMap(field: string) {
const values = {};
const definition = metadataJson.info["x-velho-nimikkeistot"][field];
const keyTitleMap = definition.nimikkeistoversiot[definition["uusin-nimikkeistoversio"]];
Object.keys(keyTitleMap).forEach((key) => {
return (values[key] = keyTitleMap[key].otsikko);
});
return values;
}

const metadata = (() => {
const tilat = extractValuesIntoMap("projekti/tila");
const vaiheet = extractValuesIntoMap("projekti/vaihe");
const organisaatiot = extractValuesIntoMap("projekti/organisaatio");
const toteutusAjankohdat = extractValuesIntoMap("projekti/arvioitu-toteutusajankohta");
return { tilat, vaiheet, organisaatiot, toteutusAjankohdat };
})();

function adaptVaylamuoto(vaylamuodot: Set<ProjektiProjektiOminaisuudetVaylamuotoEnum>) {
const values = [];
vaylamuodot.forEach((value) => values.push(`${value}`));
return values;
}

export function adaptSearchResults(searchResults: any): VelhoHakuTulos[] {
Expand All @@ -22,12 +33,21 @@ export function adaptSearchResults(searchResults: any): VelhoHakuTulos[] {
return {
oid: result.oid,
name: result.ominaisuudet.nimi,
type: adaptVaylamuoto(result.ominaisuudet.vaylamuoto),
type: result.ominaisuudet.vaylamuoto,
} as VelhoHakuTulos;
});
}
}

export function adaptProjecti(data: ProjektiProjekti) {
return data;
export function adaptProjecti(data: ProjektiProjekti): Projekti {
return {
__typename: "Projekti",
oid: "" + data.oid,
tila: metadata.tilat[`${data.ominaisuudet.tila}`],
tyyppi: metadata.vaiheet[`${data.ominaisuudet.vaihe}`],
nimi: data.ominaisuudet.nimi,
vaylamuoto: adaptVaylamuoto(data.ominaisuudet.vaylamuoto),
organisaatio: metadata.organisaatiot[`${data.ominaisuudet.tilaajaorganisaatio}`],
toteutusAjankohta: metadata.toteutusAjankohdat[`${data.ominaisuudet["arvioitu-toteutusajankohta"]}`],
};
}
51 changes: 37 additions & 14 deletions backend/src/velho/velhoClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as ProjektiRekisteri from "./projektirekisteri";
import { VelhoHakuTulos } from "../api/apiModel";
import { adaptProjecti, adaptSearchResults } from "./velhoAdapter";
import { VelhoError } from "../error/velhoError";
import { AxiosResponse } from "axios";

const axios = require("axios");

Expand All @@ -18,8 +19,16 @@ axios.interceptors.response.use((response) => {
return response;
});

axios.defaults.timeout = 28000;

const velhoApiURL = config.velhoApiURL;

function checkResponseIsOK(response: AxiosResponse, message: string) {
if (response.status !== 200) {
throw new VelhoError("Error while communicating with Velho: " + message + " Status:" + response?.statusText);
}
}

export class VelhoClient {
private accessTokenExpires;
private accessToken;
Expand All @@ -37,16 +46,17 @@ export class VelhoClient {
return this.accessToken;
}

public async searchProjects(name: string, requireExactMatch?: boolean): Promise<VelhoHakuTulos[]> {
public async searchProjects(term: string, requireExactMatch?: boolean): Promise<VelhoHakuTulos[]> {
try {
const hakuApi = await this.createHakuApi();
let searchClause;
if (requireExactMatch) {
searchClause = ["tekstikysely", ["projekti/projekti", "ominaisuudet", "nimi"], name];
searchClause = ["yhtasuuri", ["projekti/projekti", "ominaisuudet", "nimi"], term];
} else {
searchClause = ["sisaltaa-tekstin", ["projekti/projekti", "ominaisuudet", "nimi"], name];
// TODO: add kunta field into target field as well
searchClause = ["sisaltaa-tekstin", ["projekti/projekti", "ominaisuudet", "nimi"], term];
}
const result = await hakuApi.hakupalveluApiV1HakuKohdeluokatPost({
const response = await hakuApi.hakupalveluApiV1HakuKohdeluokatPost({
asetukset: {
palautettavat_kentat: [
["projekti/projekti", "oid"],
Expand All @@ -56,28 +66,41 @@ export class VelhoClient {
tyyppi: HakuPalvelu.HakulausekeAsetuksetTyyppiEnum.Kohdeluokkahaku,
jarjesta: [[["projekti/projekti", "ominaisuudet", "nimi"], "nouseva" as any]],
},
lauseke: searchClause,
lauseke: [
"ja",
[
"joukossa",
["projekti/projekti", "ominaisuudet", "vaihe"],
["vaihe/vaihe04", "vaihe/vaihe10", "vaihe/vaihe12"],
],
searchClause,
],
kohdeluokat: ["projekti/projekti"],
});
const resultCount = result.data?.osumia || 0;
checkResponseIsOK(response, "searchProjects");
const data = response.data;
const resultCount = data?.osumia || 0;
if (requireExactMatch) {
log.info(resultCount + " search results for exact term: " + name);
log.info(resultCount + " search results for exact term: " + term);
} else {
log.info(resultCount + " search results for term: " + name);
log.info(resultCount + " search results for term: " + term);
}
return adaptSearchResults(result.data.osumat);
return adaptSearchResults(data.osumat);
} catch (e) {
throw new VelhoError(e);
throw new VelhoError(e.message, e);
}
}

public async loadProject(oid: string) {
const projektiApi = await this.createProjektiRekisteriApi();
const result = await projektiApi.projektirekisteriApiV1ProjektiProjektiOidGet(oid);
if (result.status === 200) {
return adaptProjecti(result.data);
let response;
try {
response = await projektiApi.projektirekisteriApiV1ProjektiProjektiOidGet(oid);
} catch (e) {
throw new VelhoError(e.message, e);
}
throw new VelhoError("Could not load project with oid '" + oid + "'. Result:" + result.statusText);
checkResponseIsOK(response, "loadProject with oid '" + oid + "'");
return adaptProjecti(response.data);
}

private async createHakuApi() {
Expand Down
16 changes: 16 additions & 0 deletions backend/test/velho/__snapshots__/velhoAdapter.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`VelhoAdapter should adapt project from Velho successfully 1`] = `
Object {
"__typename": "Projekti",
"nimi": "Kaupungin sisääntulotien (mt 123) parantaminen välillä valtatien 1 eritasoliittymä - Päätie, Helsinki",
"oid": "100",
"organisaatio": "Pirkanmaan ELY-keskus",
"tila": "Vastaanotettu",
"toteutusAjankohta": "Toteutettavissa arviolta noin 1 vuoden päästä nykyhetkestä",
"tyyppi": "Tiesuunnitelma/Tie- ja rakennussuunnitelma",
"vaylamuoto": Array [
"tie",
],
}
`;
Loading

0 comments on commit 414d4ab

Please sign in to comment.