feat: add soap adapter foundation
This commit is contained in:
@@ -6,6 +6,7 @@ use base64::{
|
||||
engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD},
|
||||
};
|
||||
use crank_adapter_grpc::test_support as grpc_test_support;
|
||||
use crank_adapter_soap::{SoapServiceSummary, inspect_wsdl};
|
||||
use crank_core::{
|
||||
Agent, AgentId, AgentOperationBinding, AgentStatus, AgentVersion, AggregationMode,
|
||||
AsyncJobHandle, AuthConfig, AuthKind, AuthProfile, AuthProfileId, ConfigExport, ExecutionMode,
|
||||
@@ -563,6 +564,8 @@ pub struct GrpcMethodSummary {
|
||||
pub output_schema: Schema,
|
||||
}
|
||||
|
||||
pub type SoapServiceCatalog = Vec<SoapServiceSummary>;
|
||||
|
||||
fn default_operation_category() -> String {
|
||||
"general".to_owned()
|
||||
}
|
||||
@@ -2599,6 +2602,153 @@ impl AdminService {
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
}
|
||||
|
||||
#[instrument(skip(self, payload), fields(operation_id = %operation_id.as_str(), source_name = source_name.unwrap_or("service.wsdl")))]
|
||||
pub async fn upload_wsdl_file(
|
||||
&self,
|
||||
workspace_id: &WorkspaceId,
|
||||
operation_id: &OperationId,
|
||||
source_name: Option<&str>,
|
||||
payload: &[u8],
|
||||
) -> Result<DescriptorUploadResponse, ApiError> {
|
||||
let summary = self.get_operation(workspace_id, operation_id).await?;
|
||||
if summary.protocol != Protocol::Soap {
|
||||
return Err(ApiError::validation(
|
||||
"wsdl upload is only allowed for soap operations",
|
||||
));
|
||||
}
|
||||
|
||||
let services =
|
||||
inspect_wsdl(payload).map_err(|error| ApiError::validation(error.to_string()))?;
|
||||
let descriptor_id = crank_core::DescriptorId::new(new_prefixed_id("desc"));
|
||||
let storage_ref = self
|
||||
.storage
|
||||
.write_descriptor(
|
||||
operation_id,
|
||||
summary.current_draft_version,
|
||||
crank_registry::DescriptorKind::WsdlUpload,
|
||||
&descriptor_id,
|
||||
source_name,
|
||||
payload,
|
||||
)
|
||||
.await?;
|
||||
|
||||
self.registry
|
||||
.save_descriptor_metadata(SaveDescriptorMetadataRequest {
|
||||
descriptor: &crank_registry::DescriptorMetadata {
|
||||
id: descriptor_id.clone(),
|
||||
operation_id: Some(operation_id.clone()),
|
||||
version: Some(summary.current_draft_version),
|
||||
descriptor_kind: crank_registry::DescriptorKind::WsdlUpload,
|
||||
storage_ref,
|
||||
source_name: source_name.map(ToOwned::to_owned),
|
||||
package_index: Some(
|
||||
serde_json::to_value(&services)
|
||||
.map_err(|error| ApiError::internal(error.to_string()))?,
|
||||
),
|
||||
created_at: now_string()?,
|
||||
},
|
||||
})
|
||||
.await?;
|
||||
info!(
|
||||
operation_id = %operation_id.as_str(),
|
||||
descriptor_id = %descriptor_id.as_str(),
|
||||
version = summary.current_draft_version,
|
||||
"wsdl uploaded"
|
||||
);
|
||||
|
||||
Ok(DescriptorUploadResponse {
|
||||
descriptor_id: descriptor_id.as_str().to_owned(),
|
||||
version: summary.current_draft_version,
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, payload), fields(operation_id = %operation_id.as_str(), source_name = source_name.unwrap_or("schema.xsd")))]
|
||||
pub async fn upload_xsd_file(
|
||||
&self,
|
||||
workspace_id: &WorkspaceId,
|
||||
operation_id: &OperationId,
|
||||
source_name: Option<&str>,
|
||||
payload: &[u8],
|
||||
) -> Result<DescriptorUploadResponse, ApiError> {
|
||||
let summary = self.get_operation(workspace_id, operation_id).await?;
|
||||
if summary.protocol != Protocol::Soap {
|
||||
return Err(ApiError::validation(
|
||||
"xsd upload is only allowed for soap operations",
|
||||
));
|
||||
}
|
||||
|
||||
let descriptor_id = crank_core::DescriptorId::new(new_prefixed_id("desc"));
|
||||
let storage_ref = self
|
||||
.storage
|
||||
.write_descriptor(
|
||||
operation_id,
|
||||
summary.current_draft_version,
|
||||
crank_registry::DescriptorKind::XsdUpload,
|
||||
&descriptor_id,
|
||||
source_name,
|
||||
payload,
|
||||
)
|
||||
.await?;
|
||||
|
||||
self.registry
|
||||
.save_descriptor_metadata(SaveDescriptorMetadataRequest {
|
||||
descriptor: &crank_registry::DescriptorMetadata {
|
||||
id: descriptor_id.clone(),
|
||||
operation_id: Some(operation_id.clone()),
|
||||
version: Some(summary.current_draft_version),
|
||||
descriptor_kind: crank_registry::DescriptorKind::XsdUpload,
|
||||
storage_ref,
|
||||
source_name: source_name.map(ToOwned::to_owned),
|
||||
package_index: None,
|
||||
created_at: now_string()?,
|
||||
},
|
||||
})
|
||||
.await?;
|
||||
info!(
|
||||
operation_id = %operation_id.as_str(),
|
||||
descriptor_id = %descriptor_id.as_str(),
|
||||
version = summary.current_draft_version,
|
||||
"xsd uploaded"
|
||||
);
|
||||
|
||||
Ok(DescriptorUploadResponse {
|
||||
descriptor_id: descriptor_id.as_str().to_owned(),
|
||||
version: summary.current_draft_version,
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self), fields(operation_id = %operation_id.as_str(), version))]
|
||||
pub async fn list_soap_services(
|
||||
&self,
|
||||
workspace_id: &WorkspaceId,
|
||||
operation_id: &OperationId,
|
||||
version: Option<u32>,
|
||||
) -> Result<SoapServiceCatalog, ApiError> {
|
||||
let summary = self.get_operation(workspace_id, operation_id).await?;
|
||||
if summary.protocol != Protocol::Soap {
|
||||
return Err(ApiError::validation(
|
||||
"soap services are only available for soap operations",
|
||||
));
|
||||
}
|
||||
|
||||
let version = version.unwrap_or(summary.current_draft_version);
|
||||
let descriptor = self
|
||||
.registry
|
||||
.list_descriptor_metadata(operation_id, version)
|
||||
.await?
|
||||
.into_iter()
|
||||
.rev()
|
||||
.find(|descriptor| {
|
||||
descriptor.descriptor_kind == crank_registry::DescriptorKind::WsdlUpload
|
||||
})
|
||||
.ok_or_else(|| ApiError::not_found("wsdl was not uploaded"))?;
|
||||
let package_index = descriptor
|
||||
.package_index
|
||||
.ok_or_else(|| ApiError::not_found("wsdl inspection metadata is not available"))?;
|
||||
|
||||
serde_json::from_value(package_index).map_err(|error| ApiError::internal(error.to_string()))
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub async fn get_auth_profile(
|
||||
&self,
|
||||
@@ -4017,6 +4167,7 @@ fn runtime_error_code(error: &RuntimeError) -> &'static str {
|
||||
RuntimeError::GraphqlAdapter(_) => "graphql_error",
|
||||
RuntimeError::GrpcAdapter(_) => "grpc_error",
|
||||
RuntimeError::RestAdapter(_) => "rest_error",
|
||||
RuntimeError::SoapAdapter(_) => "soap_error",
|
||||
RuntimeError::WebsocketAdapter(_) => "websocket_error",
|
||||
RuntimeError::UnsupportedProtocol { .. } => "unsupported_protocol",
|
||||
RuntimeError::MissingStreamingConfig { .. } => "streaming_config_error",
|
||||
|
||||
Reference in New Issue
Block a user