Skip to content

Commit

Permalink
transport creation!
Browse files Browse the repository at this point in the history
  • Loading branch information
marcellourbani committed Nov 8, 2018
1 parent 5df9d67 commit e2402e9
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 19 deletions.
5 changes: 3 additions & 2 deletions src/adt/AdtConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ export class AdtConnection {
},
method,
headers: {
...headers,
"x-csrf-token": this._csrftoken,
Accept: "*/*"
"X-sap-adt-sessiontype": "stateful",
Accept: "*/*",
...headers
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/adt/AdtLockParser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defaultVal, mapWidth } from "../functions"
import { defaultVal, mapWith } from "../functions"

import { getNode, recxml2js } from "./AdtParserBase"

Expand All @@ -13,5 +13,5 @@ interface AdtLock {
}
export const adtLockParser = defaultVal(
[],
getNode("asx:abap/asx:values/DATA", mapWidth(recxml2js), (x: any[]) => x[0])
getNode("asx:abap/asx:values/DATA", mapWith(recxml2js), (x: any[]) => x[0])
) as (xml: string) => AdtLock
8 changes: 4 additions & 4 deletions src/adt/AdtNodeStructParser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getNode, recxml2js, parsetoPromise } from "./AdtParserBase"

import { mapWidth, ArrayToMap, filterComplex, defaultVal } from "../functions"
import { mapWith, ArrayToMap, filterComplex, defaultVal } from "../functions"
import { convertableToString } from "xml2js"

export interface ObjectNode {
Expand Down Expand Up @@ -35,7 +35,7 @@ const treecontentParser = defaultVal(
getNode(
"asx:abap/asx:values/DATA/TREE_CONTENT/SEU_ADT_REPOSITORY_OBJ_NODE",
filterComplex(true),
mapWidth(recxml2js)
mapWith(recxml2js)
)
) as (xml: string) => Array<ObjectNode>
const categoryNodeParser: (a: string) => Map<string, CategoryNode> = defaultVal(
Expand All @@ -44,7 +44,7 @@ const categoryNodeParser: (a: string) => Map<string, CategoryNode> = defaultVal(
"asx:abap/asx:values/DATA/CATEGORIES",
filterComplex(true),
"SEU_ADT_OBJECT_CATEGORY_INFO",
mapWidth(recxml2js),
mapWith(recxml2js),
ArrayToMap("CATEGORY")
)
)
Expand All @@ -55,7 +55,7 @@ const ObjectTypeParser: (a: string) => Map<string, ObjectTypeNode> = defaultVal(
"asx:abap/asx:values/DATA/OBJECT_TYPES",
filterComplex(true),
"SEU_ADT_OBJECT_TYPE_INFO",
mapWidth(recxml2js),
mapWith(recxml2js),
ArrayToMap("OBJECT_TYPE")
)
)
Expand Down
13 changes: 3 additions & 10 deletions src/adt/AdtServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { MetaFolder } from "../fs/MetaFolder"
import { AbapObjectNode, AbapNode, isAbap } from "../fs/AbapNode"
import { AbapObject, TransportStatus } from "../abap/AbapObject"
import { getRemoteList } from "../config"
import { JSON2AbapXML } from "../abap/JSONToAbapXml"
import { selectTransport } from "./AdtTransports"
export const ADTBASEURL = "/sap/bc/adt/repository/nodestructure"

// visual studio paths are hierarchic, adt ones aren't
Expand Down Expand Up @@ -59,15 +59,8 @@ export class AdtServer {
const conn = await this.connectionP
await file.abapObject.lock(conn)
if (file.abapObject.transport === TransportStatus.REQUIRED) {
const response = await conn.request(
conn.createUri("/sap/bc/adt/cts/transportchecks"),
"POST",
{
body: JSON2AbapXML({ URI: file.abapObject.getContentsUri(conn).path })
}
)
console.log(response.body)
throw new Error("transport selection not supported(yet)")
const transport = await selectTransport(file.abapObject, conn)
if (transport) file.abapObject.transport = transport
}

await file.abapObject.setContents(conn, content)
Expand Down
95 changes: 95 additions & 0 deletions src/adt/AdtTransports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { AbapObject } from "../abap/AbapObject"
import { JSON2AbapXML } from "../abap/JSONToAbapXml"
import { parsetoPromise, getNode, recxml2js } from "./AdtParserBase"
import { mapWith, flat } from "../functions"
import { AdtConnection } from "./AdtConnection"
import { window } from "vscode"

interface TransportHeader {
TRKORR: string
TRFUNCTION: string
TRSTATUS: string
TARSYSTEM: string
AS4USER: string
AS4DATE: string
AS4TIME: string
AS4TEXT: string
CLIENT: string
}
interface TransportInfo {
PGMID: string
OBJECT: string
OBJECTNAME: string
OPERATION: string
DEVCLASS: string
CTEXT: string
KORRFLAG: string
AS4USER: string
PDEVCLASS: string
DLVUNIT: string
NAMESPACE: string
RESULT: string
RECORDING: string
EXISTING_REQ_ONLY: string
TRANSPORTS: TransportHeader[]
}

export async function getTransportCandidates(
obj: AbapObject,
conn: AdtConnection
): Promise<TransportInfo> {
const response = await conn.request(
conn.createUri("/sap/bc/adt/cts/transportchecks"),
"POST",
{
body: JSON2AbapXML({ URI: obj.getContentsUri(conn).path })
}
)
const rawdata = await parsetoPromise()(response.body)
const header = getNode(
"asx:abap/asx:values/DATA",
mapWith(recxml2js),
rawdata
)[0]

const TRANSPORTS = getNode(
"asx:abap/asx:values/DATA/REQUESTS/CTS_REQUEST",
mapWith(getNode("REQ_HEADER")),
flat,
mapWith(recxml2js),
rawdata
)
return { ...header, TRANSPORTS }
}

export async function selectTransport(
obj: AbapObject,
conn: AdtConnection
): Promise<string> {
const ti = await getTransportCandidates(obj, conn)
const CREATENEW = "Create a new transport"
let selection = await window.showQuickPick([
CREATENEW,
...ti.TRANSPORTS.map(t => `${t.TRKORR} ${t.AS4TEXT}`)
])

if (!selection) return ""
if (selection === CREATENEW) {
const text = await window.showInputBox({ prompt: "Request text" })
if (!text) return ""
return createTransport(conn, obj, text, ti.DEVCLASS)
} else return selection.split(" ")[0]
}
async function createTransport(
conn: AdtConnection,
obj: AbapObject,
REQUEST_TEXT: string,
DEVCLASS: string
): Promise<string> {
let uri = obj.getContentsUri(conn)
const body = JSON2AbapXML({ DEVCLASS, REQUEST_TEXT, REF: uri.path })
uri = uri.with({ path: "/sap/bc/adt/cts/transports" })
const response = await conn.request(uri, "POST", { body })
const transport = response.body.split("/").pop()
return transport
}
2 changes: 1 addition & 1 deletion src/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const composePromise = (

//returns a function that maps an array yo the given function
// mapWith(f)(array) is the same of array.map(f), but composable
export const mapWidth = (func: any, target?: any[]) => {
export const mapWith = (func: any, target?: any[]) => {
const fn = (x: any[]) => x.map(func)
return target ? fn(target) : fn
}
Expand Down

0 comments on commit e2402e9

Please sign in to comment.