Browse Source

Merge pull request #692 from colinin/upt-5.3.4

Upt 5.3.4
pull/712/head
yx lin 3 years ago
committed by GitHub
parent
commit
5013eb9566
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 148
      apps/vue/src/components/Form/src/TabForm.vue
  2. 4
      apps/vue/src/components/Form/src/props.ts
  3. 5
      apps/vue/src/components/Form/src/types/form.ts
  4. 3
      apps/vue/src/views/platform/dataDic/components/DataItemTable.vue
  5. 45
      apps/vue/src/views/platform/dataDic/components/DataTree.vue
  6. 8
      apps/vue/src/views/platform/menu/components/MenuDrawer.vue
  7. 4
      apps/vue/src/views/platform/menu/hooks/useMenuFormContext.ts
  8. 14
      aspnet-core/LINGYUN.MicroService.WebhooksManagement.sln
  9. 28
      aspnet-core/LINGYUN.MicroService.Workflow.sln
  10. 3
      aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/FodyWeavers.xml
  11. 30
      aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/FodyWeavers.xsd
  12. 17
      aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/LINGYUN.Abp.Elsa.Activities.Webhooks.csproj
  13. 11
      aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/LINGYUN/Abp/Elsa/Activities/Webhooks/AbpElsaActivitiesWebhooksModule.cs
  14. 79
      aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/LINGYUN/Abp/Elsa/Activities/Webhooks/Activities/PublishWebhook.cs
  15. 16
      aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/LINGYUN/Abp/Elsa/Activities/Webhooks/Startup.cs
  16. 14
      aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/Microsoft/Extensions/DependencyInjection/WebhooksServiceCollectionExtensions.cs
  17. 1
      aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities/LINGYUN.Abp.Elsa.Activities.csproj
  18. 2
      aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities/LINGYUN/Abp/Elsa/Activities/AbpElsaActivitiesModule.cs
  19. 3
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/FodyWeavers.xml
  20. 30
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/FodyWeavers.xsd
  21. 15
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN.Abp.Webhooks.Core.csproj
  22. 34
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/AbpWebhooksCoreModule.cs
  23. 4
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs
  24. 0
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs
  25. 0
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs
  26. 7
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/IWebhookDefinitionProvider.cs
  27. 10
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinition.cs
  28. 0
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs
  29. 0
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs
  30. 2
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinitionProvider.cs
  31. 0
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookEvent.cs
  32. 0
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookGroupDefinition.cs
  33. 9
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookHeader.cs
  34. 0
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookPayload.cs
  35. 3
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/FodyWeavers.xml
  36. 30
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/FodyWeavers.xsd
  37. 19
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/LINGYUN.Abp.Webhooks.EventBus.csproj
  38. 19
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/LINGYUN/Abp/Webhooks/EventBus/AbpWebhooksEventBusModule.cs
  39. 71
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/LINGYUN/Abp/Webhooks/EventBus/DistributedEventBusWebhookPublisher.cs
  40. 39
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/LINGYUN/Abp/Webhooks/EventBus/WebhooksEventData.cs
  41. 4
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN.Abp.Webhooks.csproj
  42. 28
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs
  43. 2
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/BackgroundJobs/WebhookSenderJob.cs
  44. 2
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/IWebhookPublisher.cs
  45. 117
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/WebhooksEventHandler.cs
  46. 1
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj
  47. 7
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs
  48. 12
      aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/LY.MicroService.WorkflowManagement.HttpApi.Host.csproj
  49. 65
      aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/WorkflowManagementHttpApiHostModule.Configure.cs
  50. 30
      aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/WorkflowManagementHttpApiHostModule.cs
  51. 62
      aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/appsettings.Development.json
  52. 12
      docker-compose.override.yml
  53. 7
      docker-compose.yml

148
apps/vue/src/components/Form/src/TabForm.vue

@ -6,16 +6,20 @@
:model="formModel"
@keypress.enter="handleEnterPress"
>
<Row v-bind="{ ...getRow }">
<slot name="formHeader"></slot>
<Tabs v-model="activedTabKey" style="width: 100%">
<!-- fix bug: forceRender 必须强制渲染否则form验证会失效 -->
<TabPane
v-for="tabSchema in getTabSchema"
:key="tabSchema.key"
:tab="tabSchema.key"
:forceRender="true"
>
<Tabs
v-model:activeKey="activedTabKey"
:style="tabsStyle.style"
:tabBarStyle="tabsStyle.tabBarStyle"
>
<!-- fix bug: forceRender 必须强制渲染否则form验证会失效 -->
<TabPane
v-for="tabSchema in getTabSchema"
:key="tabSchema.key"
:tab="tabSchema.key"
:forceRender="true"
>
<Row v-bind="getRow">
<slot name="formHeader"></slot>
<template v-for="schema in tabSchema.schemas" :key="schema.field">
<FormItem
:tableAction="tableAction"
@ -27,19 +31,21 @@
:setFormModel="setFormModel"
>
<template #[item]="data" v-for="item in Object.keys($slots)">
<slot :name="item" v-bind="data"></slot>
<slot :name="item" v-bind="data || {}"></slot>
</template>
</FormItem>
</template>
</TabPane>
</Tabs>
</Row>
</TabPane>
</Tabs>
<Row v-bind="getRow">
<FormAction v-bind="getFormActionBindProps" @toggle-advanced="handleToggleAdvanced">
<template
#[item]="data"
v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']"
>
<slot :name="item" v-bind="data"></slot>
<slot :name="item" v-bind="data || {}"></slot>
</template>
</FormAction>
<slot name="formFooter"></slot>
@ -48,8 +54,7 @@
</template>
<script lang="ts">
import dayjs from 'dayjs';
import type { FormActionType, TabFormProps, FormSchema, TabFormSchema } from './types/form';
import type { TabFormActionType, TabFormProps, TabFormSchema } from './types/form';
import type { AdvanceState } from './types/hooks';
import type { Ref } from 'vue';
@ -70,11 +75,12 @@
import { useFormEvents } from './hooks/useFormEvents';
import { createFormContext } from './hooks/useFormContext';
import { useAutoFocus } from './hooks/useAutoFocus';
import { useTabsStyle } from '/@/hooks/component/useStyles';
import { useModalContext } from '/@/components/Modal';
import { useDebounceFn } from '@vueuse/core';
import { tabProps } from './props';
import { useDesign } from '/@/hooks/web/useDesign';
import { mergeWith } from 'lodash-es';
export default defineComponent({
name: 'TabForm',
@ -87,10 +93,11 @@
TabPane: Tabs.TabPane,
},
props: tabProps,
emits: ['advanced-change', 'reset', 'submit', 'register'],
emits: ['advanced-change', 'reset', 'submit', 'register', 'field-value-change'],
setup(props, { emit, attrs }) {
const formModel = reactive<Recordable>({});
const modalFn = useModalContext();
const tabsStyle = useTabsStyle();
const advanceState = reactive<AdvanceState>({
isAdvanced: true,
@ -104,17 +111,13 @@
const activedTabKey = ref('');
const propsRef = ref<Partial<TabFormProps>>({});
const schemaRef = ref<Nullable<TabFormSchema[]>>(null);
const formElRef = ref<Nullable<FormActionType>>(null);
const formElRef = ref<Nullable<TabFormActionType>>(null);
const { prefixCls } = useDesign('basic-form');
const getBindValue = computed(
() => ({ ...attrs, ...props, ...unref(getProps) } as Recordable),
);
// Get the basic configuration of the form
const getProps = computed((): TabFormProps => {
return mergeWith(props, unref(propsRef)) as TabFormProps;
return { ...props, ...unref(propsRef) } as TabFormProps;
});
const getFormClass = computed(() => {
@ -135,6 +138,10 @@
};
});
const getBindValue = computed(
() => ({ ...attrs, ...props, ...unref(getProps) } as Recordable),
);
const getSchema = computed((): TabFormSchema[] => {
const schemas: TabFormSchema[] = unref(schemaRef) || (unref(getProps).schemas as any);
for (const schema of schemas) {
@ -144,7 +151,7 @@
if (!Array.isArray(defaultValue)) {
schema.defaultValue = dateUtil(defaultValue);
} else {
const def: dayjs.Dayjs[] = [];
const def: any[] = [];
defaultValue.forEach((item) => {
def.push(dateUtil(item));
});
@ -153,15 +160,15 @@
}
}
if (unref(getProps).showAdvancedButton) {
return schemas.filter((schema) => schema.component !== 'Divider') as TabFormSchema[];
return schemas.filter((schema) => schema.component !== 'Divider');
} else {
return schemas as TabFormSchema[];
return schemas;
}
});
const getTabSchema = computed((): { key: string; schemas: FormSchema[] }[] => {
const getTabSchema = computed((): { key: string; schemas: TabFormSchema[] }[] => {
// const schemas = unref(getSchema);
const tabSchemas: { key: string; schemas: FormSchema[] }[] = [];
const tabSchemas: { key: string; schemas: TabFormSchema[] }[] = [];
const group = groupBy(getSchema.value, 'tab');
Object.keys(group).forEach((key) => {
tabSchemas.push({
@ -192,7 +199,7 @@
getSchema,
getProps,
isInitedDefault: isInitedDefaultRef,
formElRef: formElRef as Ref<FormActionType>,
formElRef: formElRef as Ref<TabFormActionType>,
});
const {
@ -214,7 +221,7 @@
formModel,
getSchema,
defaultValueRef,
formElRef: formElRef as Ref<FormActionType>,
formElRef: formElRef as Ref<TabFormActionType>,
schemaRef: schemaRef as Ref<TabFormSchema[]>,
handleFormValues,
});
@ -227,10 +234,12 @@
watch(
() => unref(getProps).model,
() => {
const { model } = unref(getProps);
const { model, schemas } = unref(getProps);
if (schemas?.length) {
activedTabKey.value = schemas[0].tab;
}
if (!model) return;
setFieldsValue(model);
activedTabKey.value = '';
},
{
immediate: true,
@ -241,6 +250,9 @@
() => unref(getProps).schemas,
(schemas) => {
resetSchema(schemas ?? []);
if (schemas?.length) {
activedTabKey.value = schemas[0].tab;
}
},
);
@ -257,16 +269,30 @@
if (schema?.length) {
initDefault();
isInitedDefaultRef.value = true;
activedTabKey.value = schema[0].tab;
}
},
);
watch(
() => formModel,
useDebounceFn(() => {
unref(getProps).submitOnChange && handleSubmit();
}, 300),
{ deep: true },
);
async function setProps(formProps: Partial<TabFormProps>): Promise<void> {
propsRef.value = deepMerge(unref(propsRef) || {}, formProps);
}
function setFormModel(key: string, value: any) {
formModel[key] = value;
const { validateTrigger } = unref(getBindValue);
if (!validateTrigger || validateTrigger === 'change') {
validateFields([key]).catch((_) => {});
}
emit('field-value-change', key, value);
}
function handleEnterPress(e: KeyboardEvent) {
@ -280,7 +306,11 @@
}
}
const formActionType: Partial<FormActionType> = {
function changeTab(tab: string) {
activedTabKey.value = tab;
}
const formActionType: Partial<TabFormActionType> = {
getFieldsValue,
setFieldsValue,
resetFields,
@ -294,6 +324,7 @@
validate,
submit: handleSubmit,
scrollToField: scrollToField,
changeTab: changeTab,
};
onMounted(() => {
@ -314,6 +345,7 @@
formElRef,
getSchema,
getTabSchema,
tabsStyle,
formActionType: formActionType as any,
setFormModel,
getFormClass,
@ -325,3 +357,51 @@
},
});
</script>
<style lang="less">
@prefix-cls: ~'@{namespace}-basic-form';
.@{prefix-cls} {
.ant-form-item {
&-label label::after {
margin: 0 6px 0 2px;
}
&-with-help {
margin-bottom: 0;
}
&:not(.ant-form-item-with-help) {
margin-bottom: 20px;
}
&.suffix-item {
.ant-form-item-children {
display: flex;
}
.ant-form-item-control {
margin-top: 4px;
}
.suffix {
display: inline-flex;
padding-left: 6px;
margin-top: 1px;
line-height: 1;
align-items: center;
}
}
}
.ant-form-explain {
font-size: 14px;
}
&--compact {
.ant-form-item {
margin-bottom: 8px !important;
}
}
}
</style>

4
apps/vue/src/components/Form/src/props.ts

@ -1,4 +1,4 @@
import type { FieldMapToTime, FormSchema } from './types/form';
import type { FieldMapToTime, FormSchema, TabFormSchema } from './types/form';
import type { CSSProperties, PropType } from 'vue';
import type { ColEx } from './types';
import type { TableActionType } from '/@/components/Table';
@ -120,7 +120,7 @@ export const tabProps = {
compact: propTypes.bool,
// 表单配置规则
schemas: {
type: [Array] as PropType<FormSchema[]>,
type: [Array] as PropType<TabFormSchema[]>,
default: () => [],
},
mergeDynamicData: {

5
apps/vue/src/components/Form/src/types/form.ts

@ -44,6 +44,10 @@ export interface FormActionType {
scrollToField: (name: NamePath, options?: ScrollOptions) => Promise<void>;
}
export interface TabFormActionType extends FormActionType {
changeTab: (tab: string) => void;
}
export type RegisterFn = (formInstance: FormActionType) => void;
export type UseFormReturnType = [RegisterFn, FormActionType];
@ -127,6 +131,7 @@ export interface FormProps {
export interface TabFormProps extends FormProps {
tab: string;
schemas?: TabFormSchema[];
}
export interface FormSchema {

3
apps/vue/src/views/platform/dataDic/components/DataItemTable.vue

@ -28,7 +28,7 @@
</template>
</template>
</BasicTable>
<DataItemModal @register="registerModal" @change="fetchItems" />
<DataItemModal @register="registerModal" @change="fetchItems(dataId)" />
</template>
<script lang="ts" setup>
@ -49,6 +49,7 @@
dataId: {
type: String,
retuired: true,
default: '',
},
});

45
apps/vue/src/views/platform/dataDic/components/DataTree.vue

@ -3,22 +3,30 @@
<template #extra>
<a-button type="primary" @click="openDataModal(true, {})">{{ L('Data:AddNew') }}</a-button>
</template>
<BasicTree
:tree-data="treeData"
:field-names="replaceFields"
defaultExpandLevel="1"
:before-right-click="getContentMenus"
@select="handleNodeChange"
/>
<div :style="getContentStyle" ref="contentWrapRef">
<ScrollContainer ref="contentScrollRef">
<BasicTree
:show-line="false"
:show-icon="false"
:block-node="true"
:tree-data="treeData"
:field-names="replaceFields"
defaultExpandLevel="1"
:before-right-click="getContentMenus"
@select="handleNodeChange"
/>
</ScrollContainer>
</div>
<DataModal @register="registerDataModal" @change="onLoadAllDataDic" />
<DataItemModal @register="registerItemModal" @change="(dataId) => handleNodeChange([dataId])" />
</Card>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import type { CSSProperties } from 'vue';
import { computed, ref, onMounted } from 'vue';
import { ScrollContainer } from '/@/components/Container';
import { useContentHeight } from '/@/hooks/web/useContentHeight';
import { useMessage } from '/@/hooks/web/useMessage';
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { Card } from 'ant-design-vue';
@ -26,7 +34,6 @@
import { BasicTree, ContextMenuItem } from '/@/components/Tree/index';
import { listToTree } from '/@/utils/helper/treeHelper';
import { getAll, remove } from '/@/api/platform/dataDic';
import { Data } from '/@/api/platform/model/dataModel';
import DataModal from './DataModal.vue';
import DataItemModal from './DataItemModal.vue';
@ -35,7 +42,9 @@
const { createMessage, createConfirm } = useMessage();
const { L } = useLocalization(['AppPlatform', 'AbpUi']);
const title = L('DisplayName:DataDictionary');
const treeData = ref<Data[]>([]);
const contentWrapRef = ref<any>();
const contentScrollRef = ref<any>();
const treeData = ref<any[]>([]);
const replaceFields = ref({
title: 'displayName',
key: 'id',
@ -43,6 +52,16 @@
});
const [registerItemModal, { openModal: openItemModal }] = useModal();
const [registerDataModal, { openModal: openDataModal }] = useModal();
const getFlag = computed(() => true);
const { contentHeight } = useContentHeight(
getFlag, contentWrapRef, [], []
);
const getContentStyle = computed((): CSSProperties => {
return {
width: '100%',
height: `${contentHeight.value}px`,
}
});
onMounted(onLoadAllDataDic);
@ -56,7 +75,7 @@
icon: 'ant-design:edit-outlined',
},
{
label: L('Data:AddNew'),
label: L('Data:AddChildren'),
handler: () => {
openDataModal(true, { parentId: node.eventKey });
},

8
apps/vue/src/views/platform/menu/components/MenuDrawer.vue

@ -23,10 +23,10 @@
</template>
<script lang="ts" setup>
import { nextTick, ref } from 'vue';
import { nextTick, ref, unref } from 'vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { TabForm, FormActionType } from '/@/components/Form';
import { TabForm, TabFormActionType } from '/@/components/Form';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { basicProps } from './props';
import { Menu } from '/@/api/platform/model/menuModel';
@ -39,7 +39,7 @@
const { L } = useLocalization(['AppPlatform', 'AbpUi']);
const menu = ref<Menu>({} as Menu);
const framework = ref<string | undefined>('');
const formElRef = ref<Nullable<FormActionType>>(null);
const formElRef = ref<Nullable<TabFormActionType>>(null);
const { formTitle, getFormSchemas, handleFormSubmit, fetchLayoutResource } =
useMenuFormContext({
menuModel: menu,
@ -53,6 +53,8 @@
nextTick(() => {
setDrawerProps({ confirmLoading: false });
fetchLayoutResource(dataVal.layoutId);
const formEl = unref(formElRef);
formEl?.changeTab(L('DisplayName:Basic'));
});
});

4
apps/vue/src/views/platform/menu/hooks/useMenuFormContext.ts

@ -1,5 +1,5 @@
import type { Ref } from 'vue';
import type { TabFormSchema, FormActionType } from '/@/components/Form/src/types/form';
import type { TabFormSchema, TabFormActionType } from '/@/components/Form/src/types/form';
import { unref, computed, watch, createVNode } from 'vue';
import { Checkbox } from 'ant-design-vue';
@ -14,7 +14,7 @@ import { Menu, UpdateMenu, CreateMenu } from '/@/api/platform/model/menuModel';
interface UseMenuFormContext {
menuModel: Ref<Menu>;
formElRef: Ref<Nullable<FormActionType>>;
formElRef: Ref<Nullable<TabFormActionType>>;
framework: Ref<string | undefined>,
}

14
aspnet-core/LINGYUN.MicroService.WebhooksManagement.sln

@ -35,6 +35,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Webhooks.Identi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Webhooks.Saas", "modules\webhooks\LINGYUN.Abp.Webhooks.Saas\LINGYUN.Abp.Webhooks.Saas.csproj", "{D7F2B64C-02F2-4097-80C1-DC41CE8FEE38}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Webhooks.EventBus", "modules\webhooks\LINGYUN.Abp.Webhooks.EventBus\LINGYUN.Abp.Webhooks.EventBus.csproj", "{46C08EF3-4C81-411E-B5E4-AC3A5040DC67}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Webhooks.Core", "modules\webhooks\LINGYUN.Abp.Webhooks.Core\LINGYUN.Abp.Webhooks.Core.csproj", "{BBF1C93D-EF73-4B00-919F-5E7F360BDB03}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -93,6 +97,14 @@ Global
{D7F2B64C-02F2-4097-80C1-DC41CE8FEE38}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7F2B64C-02F2-4097-80C1-DC41CE8FEE38}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7F2B64C-02F2-4097-80C1-DC41CE8FEE38}.Release|Any CPU.Build.0 = Release|Any CPU
{46C08EF3-4C81-411E-B5E4-AC3A5040DC67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46C08EF3-4C81-411E-B5E4-AC3A5040DC67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46C08EF3-4C81-411E-B5E4-AC3A5040DC67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46C08EF3-4C81-411E-B5E4-AC3A5040DC67}.Release|Any CPU.Build.0 = Release|Any CPU
{BBF1C93D-EF73-4B00-919F-5E7F360BDB03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BBF1C93D-EF73-4B00-919F-5E7F360BDB03}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BBF1C93D-EF73-4B00-919F-5E7F360BDB03}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BBF1C93D-EF73-4B00-919F-5E7F360BDB03}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -111,6 +123,8 @@ Global
{F4966BE6-CC96-4C23-9363-3BE4103F02E8} = {FB7A9794-06D2-42CF-939E-4626497B97BD}
{93BB030A-EA01-4F08-BD41-0800D838162C} = {FB7A9794-06D2-42CF-939E-4626497B97BD}
{D7F2B64C-02F2-4097-80C1-DC41CE8FEE38} = {FB7A9794-06D2-42CF-939E-4626497B97BD}
{46C08EF3-4C81-411E-B5E4-AC3A5040DC67} = {FB7A9794-06D2-42CF-939E-4626497B97BD}
{BBF1C93D-EF73-4B00-919F-5E7F360BDB03} = {FB7A9794-06D2-42CF-939E-4626497B97BD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {80ED12A5-C899-459F-A181-ADCC9D680DE5}

28
aspnet-core/LINGYUN.MicroService.Workflow.sln

@ -79,6 +79,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Elsa.Activities
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Core", "modules\common\LINGYUN.Abp.Notifications.Core\LINGYUN.Abp.Notifications.Core.csproj", "{CE1B9AD0-7CDA-4459-86A3-A3162C1095D9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Elsa.Activities.Webhooks", "modules\elsa\LINGYUN.Abp.Elsa.Activities.Webhooks\LINGYUN.Abp.Elsa.Activities.Webhooks.csproj", "{2CA34976-4A80-485C-8572-6004829BB727}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Webhooks.Core", "modules\webhooks\LINGYUN.Abp.Webhooks.Core\LINGYUN.Abp.Webhooks.Core.csproj", "{44E4EBFA-6F25-4FD7-A4B3-536C3A42677C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Webhooks", "modules\webhooks\LINGYUN.Abp.Webhooks\LINGYUN.Abp.Webhooks.csproj", "{6489B162-2B28-42B9-9AD4-EB5CCBB8AE85}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Webhooks.EventBus", "modules\webhooks\LINGYUN.Abp.Webhooks.EventBus\LINGYUN.Abp.Webhooks.EventBus.csproj", "{B6246B7A-4095-433A-B981-5D1E43CDF712}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -205,6 +213,22 @@ Global
{CE1B9AD0-7CDA-4459-86A3-A3162C1095D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE1B9AD0-7CDA-4459-86A3-A3162C1095D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE1B9AD0-7CDA-4459-86A3-A3162C1095D9}.Release|Any CPU.Build.0 = Release|Any CPU
{2CA34976-4A80-485C-8572-6004829BB727}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2CA34976-4A80-485C-8572-6004829BB727}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2CA34976-4A80-485C-8572-6004829BB727}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2CA34976-4A80-485C-8572-6004829BB727}.Release|Any CPU.Build.0 = Release|Any CPU
{44E4EBFA-6F25-4FD7-A4B3-536C3A42677C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44E4EBFA-6F25-4FD7-A4B3-536C3A42677C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44E4EBFA-6F25-4FD7-A4B3-536C3A42677C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44E4EBFA-6F25-4FD7-A4B3-536C3A42677C}.Release|Any CPU.Build.0 = Release|Any CPU
{6489B162-2B28-42B9-9AD4-EB5CCBB8AE85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6489B162-2B28-42B9-9AD4-EB5CCBB8AE85}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6489B162-2B28-42B9-9AD4-EB5CCBB8AE85}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6489B162-2B28-42B9-9AD4-EB5CCBB8AE85}.Release|Any CPU.Build.0 = Release|Any CPU
{B6246B7A-4095-433A-B981-5D1E43CDF712}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6246B7A-4095-433A-B981-5D1E43CDF712}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6246B7A-4095-433A-B981-5D1E43CDF712}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6246B7A-4095-433A-B981-5D1E43CDF712}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -243,6 +267,10 @@ Global
{9E213E6F-77CB-4068-93EB-465C47FDA8FA} = {F1CCBEC7-ACAB-4DC5-909E-D8CC2E1B7EEC}
{EEE9DF30-1901-4070-8E03-A8D8A0E10E34} = {F1CCBEC7-ACAB-4DC5-909E-D8CC2E1B7EEC}
{CE1B9AD0-7CDA-4459-86A3-A3162C1095D9} = {6DA78E72-BA55-4ECF-97DB-6258174D3E2A}
{2CA34976-4A80-485C-8572-6004829BB727} = {F1CCBEC7-ACAB-4DC5-909E-D8CC2E1B7EEC}
{44E4EBFA-6F25-4FD7-A4B3-536C3A42677C} = {6DA78E72-BA55-4ECF-97DB-6258174D3E2A}
{6489B162-2B28-42B9-9AD4-EB5CCBB8AE85} = {6DA78E72-BA55-4ECF-97DB-6258174D3E2A}
{B6246B7A-4095-433A-B981-5D1E43CDF712} = {6DA78E72-BA55-4ECF-97DB-6258174D3E2A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6BB7A5DE-DA12-44DC-BC9B-0F6CA524346F}

3
aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

17
aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/LINGYUN.Abp.Elsa.Activities.Webhooks.csproj

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RootNamespace />
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\webhooks\LINGYUN.Abp.Webhooks\LINGYUN.Abp.Webhooks.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Elsa\LINGYUN.Abp.Elsa.csproj" />
</ItemGroup>
</Project>

11
aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/LINGYUN/Abp/Elsa/Activities/Webhooks/AbpElsaActivitiesWebhooksModule.cs

@ -0,0 +1,11 @@
using LINGYUN.Abp.Webhooks;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Elsa.Activities.Webhooks;
[DependsOn(
typeof(AbpElsaModule),
typeof(AbpWebhooksModule))]
public class AbpElsaActivitiesWebhooksModule : AbpModule
{
}

79
aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/LINGYUN/Abp/Elsa/Activities/Webhooks/Activities/PublishWebhook.cs

@ -0,0 +1,79 @@
using Elsa;
using Elsa.ActivityResults;
using Elsa.Attributes;
using Elsa.Design;
using Elsa.Expressions;
using Elsa.Providers.WorkflowStorage;
using Elsa.Services;
using Elsa.Services.Models;
using LINGYUN.Abp.Webhooks;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Elsa.Activities.Webhooks;
[Action(
Category = "PublishWebhook",
Description = "Sends webhooks to subscriptions.",
Outcomes = new[] { OutcomeNames.Done })]
public class PublishWebhook : Activity
{
private readonly IWebhookPublisher _webhookPublisher;
[ActivityInput(
Hint = "Unique name of the webhook.",
SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid })]
public string WebhooName { get; set; }
[ActivityInput(
Hint = "Data to send.",
UIHint = ActivityInputUIHints.MultiLine,
SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid },
DefaultWorkflowStorageProvider = TransientWorkflowStorageProvider.ProviderName
)]
public object WebhookData { get; set; }
[ActivityInput(
Hint = "If true, It sends the exact same data as the parameter to clients.",
SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid })]
public bool SendExactSameData { get; set; }
[ActivityInput(
Hint = "If true, webhook will only contain given headers. If false given headers will be added to predefined headers in subscription.",
SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid })]
public bool UseOnlyGivenHeaders { get; set; }
[ActivityInput(
Hint = "That headers will be sent with the webhook.",
UIHint = ActivityInputUIHints.MultiLine, DefaultSyntax = SyntaxNames.Json,
SupportedSyntaxes = new[] { SyntaxNames.Json, SyntaxNames.JavaScript, SyntaxNames.Liquid },
Category = PropertyCategories.Advanced
)]
public IDictionary<string, string> Headers { get; set; }
public PublishWebhook(
IWebhookPublisher webhookPublisher)
{
_webhookPublisher = webhookPublisher;
}
protected async override ValueTask<IActivityExecutionResult> OnExecuteAsync(ActivityExecutionContext context)
{
var tenantId = context.GetTenantId();
await _webhookPublisher.PublishAsync(
WebhooName,
WebhookData,
tenantId,
SendExactSameData,
new WebhookHeader
{
UseOnlyGivenHeaders = UseOnlyGivenHeaders,
Headers = Headers
});
return Done();
}
}

16
aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/LINGYUN/Abp/Elsa/Activities/Webhooks/Startup.cs

@ -0,0 +1,16 @@
using Elsa.Attributes;
using Elsa.Options;
using Elsa.Services.Startup;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace LINGYUN.Abp.Elsa.Activities.Webhooks;
[Feature("Webhooks")]
public class Startup : StartupBase
{
public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration)
{
elsa.AddWebhooksActivities();
}
}

14
aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities.Webhooks/Microsoft/Extensions/DependencyInjection/WebhooksServiceCollectionExtensions.cs

@ -0,0 +1,14 @@
using Elsa.Options;
using LINGYUN.Abp.Elsa.Activities.Webhooks;
namespace Microsoft.Extensions.DependencyInjection;
public static class WebhooksServiceCollectionExtensions
{
public static ElsaOptionsBuilder AddWebhooksActivities(this ElsaOptionsBuilder options)
{
options.AddActivity<PublishWebhook>();
return options;
}
}

1
aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities/LINGYUN.Abp.Elsa.Activities.csproj

@ -19,6 +19,7 @@
<ProjectReference Include="..\LINGYUN.Abp.Elsa.Activities.IM\LINGYUN.Abp.Elsa.Activities.IM.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Elsa.Activities.Notifications\LINGYUN.Abp.Elsa.Activities.Notifications.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Elsa.Activities.Sms\LINGYUN.Abp.Elsa.Activities.Sms.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Elsa.Activities.Webhooks\LINGYUN.Abp.Elsa.Activities.Webhooks.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Elsa\LINGYUN.Abp.Elsa.csproj" />
</ItemGroup>

2
aspnet-core/modules/elsa/LINGYUN.Abp.Elsa.Activities/LINGYUN/Abp/Elsa/Activities/AbpElsaActivitiesModule.cs

@ -5,6 +5,7 @@ using LINGYUN.Abp.Elsa.Activities.Emailing;
using LINGYUN.Abp.Elsa.Activities.IM;
using LINGYUN.Abp.Elsa.Activities.Notifications;
using LINGYUN.Abp.Elsa.Activities.Sms;
using LINGYUN.Abp.Elsa.Activities.Webhooks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
@ -30,6 +31,7 @@ public class AbpElsaActivitiesModule : AbpModule
typeof(Notifications.Startup),
typeof(Sms.Startup),
typeof(IM.Startup),
typeof(Webhooks.Startup),
};
PreConfigure<ElsaOptionsBuilder>(elsa =>

3
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

15
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN.Abp.Webhooks.Core.csproj

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Features" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
</Project>

34
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/AbpWebhooksCoreModule.cs

@ -0,0 +1,34 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using Volo.Abp.Features;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Webhooks;
[DependsOn(typeof(AbpFeaturesModule))]
public class AbpWebhooksCoreModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
AutoAddDefinitionProviders(context.Services);
}
private static void AutoAddDefinitionProviders(IServiceCollection services)
{
var definitionProviders = new List<Type>();
services.OnRegistred(context =>
{
if (typeof(IWebhookDefinitionProvider).IsAssignableFrom(context.ImplementationType))
{
definitionProviders.Add(context.ImplementationType);
}
});
services.Configure<AbpWebhooksOptions>(options =>
{
options.DefinitionProviders.AddIfNotContains(definitionProviders);
});
}
}

4
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/AbpWebhooksOptions.cs

@ -22,7 +22,7 @@ public class AbpWebhooksOptions
/// </summary>
public int MaxConsecutiveFailCountBeforeDeactivateSubscription { get; set; }
public ITypeList<WebhookDefinitionProvider> DefinitionProviders { get; }
public ITypeList<IWebhookDefinitionProvider> DefinitionProviders { get; }
public AbpWebhooksOptions()
{
@ -30,6 +30,6 @@ public class AbpWebhooksOptions
MaxSendAttemptCount = 5;
MaxConsecutiveFailCountBeforeDeactivateSubscription = MaxSendAttemptCount * 3;
DefinitionProviders = new TypeList<WebhookDefinitionProvider>();
DefinitionProviders = new TypeList<IWebhookDefinitionProvider>();
}
}

0
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/IWebhookDefinitionContext.cs

0
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/IWebhookDefinitionManager.cs

7
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/IWebhookDefinitionProvider.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.Webhooks
{
public interface IWebhookDefinitionProvider
{
void Define(IWebhookDefinitionContext context);
}
}

10
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinition.cs

@ -25,6 +25,8 @@ namespace LINGYUN.Abp.Webhooks
public List<string> RequiredFeatures { get; set; }
public Dictionary<string, object> Properties { get; }
public WebhookDefinition(string name, ILocalizableString displayName = null, ILocalizableString description = null)
{
if (name.IsNullOrWhiteSpace())
@ -37,6 +39,7 @@ namespace LINGYUN.Abp.Webhooks
Description = description;
RequiredFeatures = new List<string>();
Properties = new Dictionary<string, object>();
}
public WebhookDefinition WithFeature(params string[] features)
@ -49,6 +52,13 @@ namespace LINGYUN.Abp.Webhooks
return this;
}
public WebhookDefinition WithProperty(string key, object value)
{
Properties[key] = value;
return this;
}
public override string ToString()
{
return $"[{nameof(WebhookDefinition)} {Name}]";

0
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinitionContext.cs

0
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs

2
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookDefinitionProvider.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinitionProvider.cs

@ -2,7 +2,7 @@
namespace LINGYUN.Abp.Webhooks
{
public abstract class WebhookDefinitionProvider : ITransientDependency
public abstract class WebhookDefinitionProvider : IWebhookDefinitionProvider, ITransientDependency
{
/// <summary>
/// Used to add/manipulate webhook definitions.

0
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookEvent.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookEvent.cs

0
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookGroupDefinition.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookGroupDefinition.cs

9
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookHeader.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookHeader.cs

@ -1,7 +1,9 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace LINGYUN.Abp.Webhooks
{
[Serializable]
public class WebhookHeader
{
/// <summary>
@ -14,5 +16,10 @@ namespace LINGYUN.Abp.Webhooks
/// That headers will be sent with the webhook.
/// </summary>
public IDictionary<string, string> Headers { get; set; }
public WebhookHeader()
{
Headers = new Dictionary<string, string>();
}
}
}

0
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookPayload.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookPayload.cs

3
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

19
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/LINGYUN.Abp.Webhooks.EventBus.csproj

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.EventBus" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.Webhooks\LINGYUN.Abp.Webhooks.csproj" />
</ItemGroup>
</Project>

19
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/LINGYUN/Abp/Webhooks/EventBus/AbpWebhooksEventBusModule.cs

@ -0,0 +1,19 @@
using Volo.Abp.EventBus;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Webhooks.EventBus;
[DependsOn(
typeof(AbpWebhooksModule),
typeof(AbpEventBusModule))]
public class AbpWebhooksEventBusModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.UnsupportedTypes.TryAdd<WebhooksEventData>();
});
}
}

71
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/LINGYUN/Abp/Webhooks/EventBus/DistributedEventBusWebhookPublisher.cs

@ -0,0 +1,71 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
namespace LINGYUN.Abp.Webhooks.EventBus;
[Dependency(ReplaceServices = true)]
public class DistributedEventBusWebhookPublisher : IWebhookPublisher, ITransientDependency
{
protected IDistributedEventBus EventBus { get; }
public DistributedEventBusWebhookPublisher(IDistributedEventBus eventBus)
{
EventBus = eventBus;
}
public async virtual Task PublishAsync(
string webhookName,
object data,
bool sendExactSameData = false,
WebhookHeader headers = null)
{
var eventData = new WebhooksEventData(
webhookName,
data,
sendExactSameData,
headers);
await PublishAsync(eventData);
}
public async virtual Task PublishAsync(
string webhookName,
object data,
Guid? tenantId,
bool sendExactSameData = false,
WebhookHeader headers = null)
{
var eventData = new WebhooksEventData(
webhookName,
data,
sendExactSameData,
headers,
new Guid?[] { tenantId });
await PublishAsync(eventData);
}
public async virtual Task PublishAsync(
Guid?[] tenantIds,
string webhookName,
object data,
bool sendExactSameData = false,
WebhookHeader headers = null)
{
var eventData = new WebhooksEventData(
webhookName,
data,
sendExactSameData,
headers,
tenantIds);
await PublishAsync(eventData);
}
protected async virtual Task PublishAsync(WebhooksEventData eventData)
{
await EventBus.PublishAsync(eventData);
}
}

39
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.EventBus/LINGYUN/Abp/Webhooks/EventBus/WebhooksEventData.cs

@ -0,0 +1,39 @@
using System;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.Webhooks.EventBus;
[Serializable]
[EventName("abp.webhooks.events")]
public class WebhooksEventData
{
public Guid?[] TenantIds { get; set; }
public string WebhookName { get; set; }
public object Data { get; set; }
public bool SendExactSameData { get; set; }
public WebhookHeader Headers { get; set; }
public WebhooksEventData()
{
Headers = new WebhookHeader();
TenantIds = new Guid?[0];
}
public WebhooksEventData(
string webhookName,
object data,
bool sendExactSameData = false,
WebhookHeader headers = null,
Guid?[] tenantIds = null)
{
WebhookName = webhookName;
Data = data;
SendExactSameData = sendExactSameData;
Headers = headers ?? new WebhookHeader();
TenantIds = tenantIds ?? new Guid?[0];
}
}

4
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN.Abp.Webhooks.csproj

@ -15,4 +15,8 @@
<PackageReference Include="Volo.Abp.Http.Client" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.Webhooks.Core\LINGYUN.Abp.Webhooks.Core.csproj" />
</ItemGroup>
</Project>

28
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs

@ -1,27 +1,19 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Features;
using Volo.Abp.Guids;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Webhooks;
[DependsOn(typeof(AbpWebhooksCoreModule))]
[DependsOn(typeof(AbpBackgroundJobsAbstractionsModule))]
[DependsOn(typeof(AbpFeaturesModule))]
[DependsOn(typeof(AbpGuidsModule))]
[DependsOn(typeof(AbpHttpClientModule))]
public class AbpWebhooksModule : AbpModule
{
internal const string WebhooksClient = "__Abp_Webhooks_HttpClient";
public override void PreConfigureServices(ServiceConfigurationContext context)
{
AutoAddDefinitionProviders(context.Services);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var options = context.Services.ExecutePreConfiguredActions<AbpWebhooksOptions>();
@ -31,22 +23,4 @@ public class AbpWebhooksModule : AbpModule
client.Timeout = options.TimeoutDuration;
});
}
private static void AutoAddDefinitionProviders(IServiceCollection services)
{
var definitionProviders = new List<Type>();
services.OnRegistred(context =>
{
if (typeof(WebhookDefinitionProvider).IsAssignableFrom(context.ImplementationType))
{
definitionProviders.Add(context.ImplementationType);
}
});
services.Configure<AbpWebhooksOptions>(options =>
{
options.DefinitionProviders.AddIfNotContains(definitionProviders);
});
}
}

2
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs → aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/BackgroundJobs/WebhookSenderJob.cs

@ -6,7 +6,7 @@ using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.Webhooks.BackgroundWorker
namespace LINGYUN.Abp.Webhooks.BackgroundJobs
{
public class WebhookSenderJob : AsyncBackgroundJob<WebhookSenderArgs>, ITransientDependency
{

2
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/IWebhookPublisher.cs

@ -6,7 +6,7 @@ namespace LINGYUN.Abp.Webhooks
public interface IWebhookPublisher
{
/// <summary>
/// Sends webhooks to current tenant subscriptions (<see cref="IAbpSession.TenantId"/>). with given data, (Checks permissions)
/// Sends webhooks to current tenant subscriptions (<see cref="Volo.Abp.MultiTenancy.ICurrentTenant.TenantId"/>). with given data, (Checks permissions)
/// </summary>
/// <param name="webhookName"><see cref="WebhookDefinition.Name"/></param>
/// <param name="data">data to send</param>

117
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/EventBus/Handlers/WebhooksEventHandler.cs

@ -0,0 +1,117 @@
using LINGYUN.Abp.Webhooks;
using LINGYUN.Abp.Webhooks.EventBus;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
namespace LY.MicroService.WebhooksManagement.EventBus.Handlers;
public class WebhooksEventHandler :
IDistributedEventHandler<WebhooksEventData>,
ITransientDependency
{
public IWebhookEventStore WebhookEventStore { get; set; }
private readonly ICurrentTenant _currentTenant;
private readonly IBackgroundJobManager _backgroundJobManager;
private readonly IWebhookSubscriptionManager _webhookSubscriptionManager;
public WebhooksEventHandler(
IWebhookSubscriptionManager webhookSubscriptionManager,
ICurrentTenant currentTenant,
IBackgroundJobManager backgroundJobManager)
{
_currentTenant = currentTenant;
_backgroundJobManager = backgroundJobManager;
_webhookSubscriptionManager = webhookSubscriptionManager;
WebhookEventStore = NullWebhookEventStore.Instance;
}
public async virtual Task HandleEventAsync(WebhooksEventData eventData)
{
var subscriptions = await _webhookSubscriptionManager
.GetAllSubscriptionsOfTenantsIfFeaturesGrantedAsync(
eventData.TenantIds,
eventData.WebhookName);
await PublishAsync(eventData.WebhookName, eventData.Data, subscriptions, eventData.SendExactSameData, eventData.Headers);
}
protected async virtual Task PublishAsync(
string webhookName,
object data,
List<WebhookSubscriptionInfo> webhookSubscriptions,
bool sendExactSameData = false,
WebhookHeader headers = null)
{
if (webhookSubscriptions.IsNullOrEmpty())
{
return;
}
var subscriptionsGroupedByTenant = webhookSubscriptions.GroupBy(x => x.TenantId);
foreach (var subscriptionGroupedByTenant in subscriptionsGroupedByTenant)
{
var webhookInfo = await SaveAndGetWebhookAsync(subscriptionGroupedByTenant.Key, webhookName, data);
foreach (var webhookSubscription in subscriptionGroupedByTenant)
{
var headersToSend = webhookSubscription.Headers;
if (headers != null)
{
if (headers.UseOnlyGivenHeaders)//do not use the headers defined in subscription
{
headersToSend = headers.Headers;
}
else
{
//use the headers defined in subscription. If additional headers has same header, use additional headers value.
foreach (var additionalHeader in headers.Headers)
{
headersToSend[additionalHeader.Key] = additionalHeader.Value;
}
}
}
await _backgroundJobManager.EnqueueAsync(new WebhookSenderArgs
{
TenantId = webhookSubscription.TenantId,
WebhookEventId = webhookInfo.Id,
Data = webhookInfo.Data,
WebhookName = webhookInfo.WebhookName,
WebhookSubscriptionId = webhookSubscription.Id,
Headers = headersToSend,
Secret = webhookSubscription.Secret,
WebhookUri = webhookSubscription.WebhookUri,
SendExactSameData = sendExactSameData
});
}
}
}
protected async virtual Task<WebhookEvent> SaveAndGetWebhookAsync(
Guid? tenantId,
string webhookName,
object data)
{
var webhookInfo = new WebhookEvent
{
WebhookName = webhookName,
Data = JsonConvert.SerializeObject(data),
TenantId = tenantId
};
var webhookId = await WebhookEventStore.InsertAndGetIdAsync(webhookInfo);
webhookInfo.Id = webhookId;
return webhookInfo;
}
}

1
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj

@ -47,6 +47,7 @@
<ItemGroup>
<ProjectReference Include="..\..\modules\authorization\LINGYUN.Abp.Authorization.OrganizationUnits\LINGYUN.Abp.Authorization.OrganizationUnits.csproj" />
<ProjectReference Include="..\..\modules\webhooks\LINGYUN.Abp.Webhooks.EventBus\LINGYUN.Abp.Webhooks.EventBus.csproj" />
<ProjectReference Include="..\..\modules\webhooks\LINGYUN.Abp.Webhooks.Identity\LINGYUN.Abp.Webhooks.Identity.csproj" />
<ProjectReference Include="..\..\modules\webhooks\LINGYUN.Abp.Webhooks.Saas\LINGYUN.Abp.Webhooks.Saas.csproj" />
<ProjectReference Include="..\..\modules\webhooks\LINGYUN.Abp.WebhooksManagement.Application\LINGYUN.Abp.WebhooksManagement.Application.csproj" />

7
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs

@ -37,6 +37,9 @@ using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.Swashbuckle;
using LINGYUN.Abp.Http.Client.Wrapper;
using LINGYUN.Abp.Dapr.Client.Wrapper;
using Microsoft.Extensions.DependencyInjection.Extensions;
using LINGYUN.Abp.Webhooks;
using LINGYUN.Abp.Webhooks.EventBus;
namespace LY.MicroService.WebhooksManagement;
@ -50,6 +53,7 @@ namespace LY.MicroService.WebhooksManagement;
typeof(WebhooksManagementEntityFrameworkCoreModule),
typeof(AbpWebhooksIdentityModule),
typeof(AbpWebhooksSaasModule),
typeof(AbpWebhooksEventBusModule),
typeof(AbpBackgroundTasksQuartzModule),
typeof(AbpBackgroundTasksDistributedLockingModule),
typeof(AbpBackgroundTasksExceptionHandlingModule),
@ -107,6 +111,9 @@ public partial class WebhooksManagementHttpApiHostModule : AbpModule
ConfigureDistributedLock(context.Services, configuration);
ConfigureSeedWorker(context.Services, hostingEnvironment.IsDevelopment());
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment());
// 分布式事件发布者不在这个项目使用, 强制替换
context.Services.Replace(ServiceDescriptor.Transient<IWebhookPublisher, DefaultWebhookPublisher>());
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)

12
aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/LY.MicroService.WorkflowManagement.HttpApi.Host.csproj

@ -7,6 +7,10 @@
<ItemGroup>
<PackageReference Include="AgileConfig.Client" Version="$(AgileConfigClientPackageVersion)" />
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageReference Include="DotNetCore.CAP.MySql" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageReference Include="DotNetCore.CAP.OpenTelemetry" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageReference Include="Elsa.Activities.Email" Version="$(ElsaPackageVersion)" />
<PackageReference Include="Elsa.Activities.Http" Version="$(ElsaPackageVersion)" />
<PackageReference Include="Elsa.Activities.UserTask" Version="$(ElsaPackageVersion)" />
@ -22,6 +26,7 @@
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="$(MicrosoftPackageVersion)" />
<PackageReference Include="DistributedLock.Redis" Version="$(DistributedLockRedisPackageVersion)" />
<PackageReference Include="Quartz.Serialization.Json" Version="$(QuartzNETPackageVersion)" />
<PackageReference Include="Serilog.AspNetCore" Version="$(SerilogAspNetCorePackageVersion)" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="$(SerilogEnrichersEnvironmentPackageVersion)" />
<PackageReference Include="Serilog.Enrichers.Assembly" Version="$(SerilogEnrichersAssemblyPackageVersion)" />
@ -44,6 +49,8 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\authorization\LINGYUN.Abp.Authorization.OrganizationUnits\LINGYUN.Abp.Authorization.OrganizationUnits.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Data.DbMigrator\LINGYUN.Abp.Data.DbMigrator.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Http.Client.Wrapper\LINGYUN.Abp.Http.Client.Wrapper.csproj" />
@ -59,6 +66,11 @@
<ProjectReference Include="..\..\modules\localization\LINGYUN.Abp.AspNetCore.Mvc.Localization\LINGYUN.Abp.AspNetCore.Mvc.Localization.csproj" />
<ProjectReference Include="..\..\modules\localization\LINGYUN.Abp.Localization.CultureMap\LINGYUN.Abp.Localization.CultureMap.csproj" />
<ProjectReference Include="..\..\modules\oss-management\LINGYUN.Abp.BlobStoring.OssManagement\LINGYUN.Abp.BlobStoring.OssManagement.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.BackgroundTasks.Quartz\LINGYUN.Abp.BackgroundTasks.Quartz.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.BackgroundTasks.DistributedLocking\LINGYUN.Abp.BackgroundTasks.DistributedLocking.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.BackgroundTasks.ExceptionHandling\LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.TaskManagement.EntityFrameworkCore\LINGYUN.Abp.TaskManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\text-templating\LINGYUN.Abp.TextTemplating.EntityFrameworkCore\LINGYUN.Abp.TextTemplating.EntityFrameworkCore.csproj" />
</ItemGroup>
</Project>

65
aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/WorkflowManagementHttpApiHostModule.Configure.cs

@ -1,6 +1,8 @@
using Elsa;
using DotNetCore.CAP;
using Elsa;
using Elsa.Options;
using Elsa.Rebus.RabbitMq;
using LINGYUN.Abp.BackgroundTasks;
using LINGYUN.Abp.BlobStoring.OssManagement;
using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Emailing;
@ -18,8 +20,10 @@ using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Quartz;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Unicode;
@ -34,6 +38,7 @@ using Volo.Abp.Json;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Quartz;
using Volo.Abp.Threading;
using Volo.Abp.VirtualFileSystem;
@ -42,7 +47,7 @@ namespace LY.MicroService.WorkflowManagement;
public partial class WorkflowManagementHttpApiHostModule
{
private const string DefaultCorsPolicyName = "Default";
private const string ApplicationName = "WorkflowManagement";
private const string ApplicationName = "Workflow";
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
private void PreConfigureFeature()
@ -58,6 +63,60 @@ public partial class WorkflowManagementHttpApiHostModule
AbpSerilogEnrichersConsts.ApplicationName = ApplicationName;
}
private void PreConfigureCAP(IConfiguration configuration)
{
PreConfigure<CapOptions>(options =>
{
options
.UseMySql(mySqlOptions =>
{
configuration.GetSection("CAP:MySql").Bind(mySqlOptions);
})
.UseRabbitMQ(rabbitMQOptions =>
{
configuration.GetSection("CAP:RabbitMQ").Bind(rabbitMQOptions);
})
.UseDashboard();
});
}
private void PreConfigureQuartz(IConfiguration configuration)
{
PreConfigure<AbpQuartzOptions>(options =>
{
// 如果使用持久化存储, 则配置quartz持久层
if (configuration.GetSection("Quartz:UsePersistentStore").Get<bool>())
{
var settings = configuration.GetSection("Quartz:Properties").Get<Dictionary<string, string>>();
if (settings != null)
{
foreach (var setting in settings)
{
options.Properties[setting.Key] = setting.Value;
}
}
options.Configurator += (config) =>
{
config.UsePersistentStore(store =>
{
store.UseProperties = false;
store.UseJsonSerializer();
});
};
}
});
}
private void ConfigureBackgroundTasks()
{
Configure<AbpBackgroundTasksOptions>(options =>
{
options.NodeName = ApplicationName;
});
}
private void PreConfigureElsa(IServiceCollection services, IConfiguration configuration)
{
var elsaSection = configuration.GetSection("Elsa");
@ -255,7 +314,7 @@ public partial class WorkflowManagementHttpApiHostModule
services.AddSwaggerGen(
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "WorkflowManagement API", Version = "v1" });
options.SwaggerDoc("v1", new OpenApiInfo { Title = "Workflow API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme

30
aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/WorkflowManagementHttpApiHostModule.cs

@ -1,11 +1,17 @@
using Elsa;
using DotNetCore.CAP;
using Elsa;
using LINGYUN.Abp.AspNetCore.Mvc.Localization;
using LINGYUN.Abp.AspNetCore.Mvc.Wrapper;
using LINGYUN.Abp.AuditLogging.Elasticsearch;
using LINGYUN.Abp.Authorization.OrganizationUnits;
using LINGYUN.Abp.BackgroundTasks.DistributedLocking;
using LINGYUN.Abp.BackgroundTasks.ExceptionHandling;
using LINGYUN.Abp.BackgroundTasks.Quartz;
using LINGYUN.Abp.BlobStoring.OssManagement;
using LINGYUN.Abp.Data.DbMigrator;
using LINGYUN.Abp.Elsa;
using LINGYUN.Abp.Elsa.Activities;
using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling.Emailing;
using LINGYUN.Abp.Http.Client.Wrapper;
using LINGYUN.Abp.Localization.CultureMap;
@ -13,6 +19,7 @@ using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore;
using LINGYUN.Abp.Saas.EntityFrameworkCore;
using LINGYUN.Abp.Serilog.Enrichers.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.TaskManagement.EntityFrameworkCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
@ -31,6 +38,7 @@ using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.Swashbuckle;
using Volo.Abp.TextTemplating.Scriban;
namespace LY.MicroService.WorkflowManagement;
@ -43,21 +51,28 @@ namespace LY.MicroService.WorkflowManagement;
typeof(AbpElsaModule),
typeof(AbpElsaServerModule),
typeof(AbpElsaActivitiesModule),
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpEmailingExceptionHandlingModule),
typeof(AbpHttpClientIdentityModelWebModule),
typeof(AbpAspNetCoreMultiTenancyModule),
typeof(AbpAspNetCoreMvcLocalizationModule),
typeof(AbpBackgroundTasksQuartzModule),
typeof(AbpBackgroundTasksDistributedLockingModule),
typeof(AbpBackgroundTasksExceptionHandlingModule),
typeof(TaskManagementEntityFrameworkCoreModule),
typeof(AbpFeatureManagementEntityFrameworkCoreModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpSaasEntityFrameworkCoreModule),
typeof(AbpLocalizationManagementEntityFrameworkCoreModule),
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpAuthorizationOrganizationUnitsModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpTextTemplatingScribanModule),
typeof(AbpDataDbMigratorModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpAspNetCoreMvcModule),
typeof(AbpSwashbuckleModule),
typeof(AbpCAPEventBusModule),
typeof(AbpLocalizationCultureMapModule),
typeof(AbpHttpClientWrapperModule),
typeof(AbpAspNetCoreMvcWrapperModule),
@ -71,6 +86,8 @@ public partial class WorkflowManagementHttpApiHostModule : AbpModule
PreConfigureApp();
PreConfigureFeature();
PreConfigureCAP(configuration);
PreConfigureQuartz(configuration);
PreConfigureElsa(context.Services, configuration);
}
@ -83,6 +100,7 @@ public partial class WorkflowManagementHttpApiHostModule : AbpModule
ConfigureEndpoints();
ConfigureLocalization();
ConfigureJsonSerializer();
ConfigureBackgroundTasks();
ConfigureExceptionHandling();
ConfigureVirtualFileSystem();
ConfigureCaching(configuration);
@ -103,16 +121,18 @@ public partial class WorkflowManagementHttpApiHostModule : AbpModule
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
app.UseStaticFiles();
// 本地化
app.UseMapRequestLocalization();
app.UseCorrelationId();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(DefaultCorsPolicyName);
app.UseElsaFeatures();
app.UseAuthentication();
app.UseJwtTokenMiddleware();
app.UseMultiTenancy();
app.UseAbpRequestLocalization();
app.UseAuthorization();
app.UseCapDashboard();
app.UseSwagger();
app.UseAbpSwaggerUI(options =>
{

62
aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/appsettings.Development.json

@ -1,11 +1,11 @@
{
"AgileConfig": {
"env": "DEV",
"appId": "LINGYUN.Abp.WorkflowManagement",
"appId": "LINGYUN.Abp.Workflow",
"secret": "1q2w3E*",
"nodes": "http://127.0.0.1:15000",
"name": "LINGYUN.Abp.WorkflowManagement",
"tag": "LINGYUN.Abp.WorkflowManagement"
"name": "LINGYUN.Abp.Workflow",
"tag": "LINGYUN.Abp.Workflow"
},
"App": {
"TrackingEntitiesChanged": true,
@ -22,6 +22,21 @@
"AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"AbpSaas": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456"
},
"Quartz": {
"UsePersistentStore": false,
"Properties": {
"quartz.jobStore.dataSource": "tkm",
"quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz",
"quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.MySQLDelegate,Quartz",
"quartz.dataSource.tkm.connectionString": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"quartz.dataSource.tkm.connectionStringName": "TaskManagement",
"quartz.dataSource.tkm.provider": "MySqlConnector",
"quartz.jobStore.clustered": "true",
"quartz.serializer.type": "json",
"quartz.scheduler.instanceName": "workflow",
"quartz.scheduler.instanceId": "212c489d-cb5d-4e0a-bde9-80d4a29d379b"
}
},
"Elsa": {
"Features": {
"DefaultPersistence": {
@ -45,6 +60,7 @@
"Notification": true,
"Sms": true,
"IM": true,
"PublishWebhook": true,
"Webhooks": {
"Enabled": true,
"ConnectionStringIdentifier": "Workflow",
@ -66,7 +82,7 @@
},
"Rebus": {
"RabbitMQ": {
"Connection": "amqp://admin:662874@127.0.0.1:5672/"
"Connection": "amqp://guest:guest@127.0.0.1:5672/"
}
},
"Server": {
@ -93,27 +109,33 @@
"OssManagement": {
"Bucket": "workflow"
},
"RabbitMQ": {
"Connections": {
"AbpWorkflowCore": {
"HostName": "127.0.0.1",
"Port": 5672,
"UserName": "admin",
"Password": "123456",
"VirtualHost": "/"
}
},
"EventBus": {
"ConnectionName": "AbpWorkflowCore",
"ClientName": "workflow.server",
"ExchangeName": "AbpWorkflowCore"
}
},
"DistributedLock": {
"Redis": {
"Configuration": "127.0.0.1,defaultDatabase=15"
}
},
"CAP": {
"EventBus": {
"DefaultGroupName": "Workflow",
"GroupNamePrefix": "Dev",
"Version": "v1",
"FailedRetryInterval": 300,
"FailedRetryCount": 10,
"CollectorCleaningInterval": 3600000
},
"MySql": {
"TableNamePrefix": "wf",
"ConnectionString": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456"
},
"RabbitMQ": {
"HostName": "127.0.0.1",
"Port": 5672,
"UserName": "guest",
"Password": "guest",
"ExchangeName": "LINGYUN.Abp.Application",
"VirtualHost": "/"
}
},
"Redis": {
"Configuration": "127.0.0.1,defaultDatabase=10",
"InstanceName": "LINGYUN.Abp.Application"

12
docker-compose.override.yml

@ -96,6 +96,18 @@ services:
networks:
- framework
workflow-api:
build:
context: ./aspnet-core/services/Publish/workflow
volumes:
- /var/opt/abp/logs/workflow:/app/Logs
- /var/opt/abp/data/workflow/Modules:/app/Modules
depends_on:
- sts-server
restart: always
networks:
- framework
internal-apigateway:
build:
context: ./aspnet-core/services/Publish/internal-apigateway

7
docker-compose.yml

@ -50,6 +50,13 @@ services:
ports:
- "30045:80"
workflow-api:
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://0.0.0.0:80
ports:
- "30050:80"
sts-server:
environment:
- ASPNETCORE_ENVIRONMENT=Production

Loading…
Cancel
Save