جعل وظائف SIL محمولة بين الإصدارات في Jira

تحية للجميع!

في هذه المقالة ، نواصل النقاش حول تطوير وظائفنا الخاصة لـ SIL. يمكن قراءة المقال السابق هنا .

واحدة من المزايا الرئيسية لـ SIL هي أن الرمز المكتوب في SIL سيعمل على جميع إصدارات Jira ، لذلك نحتاج إلى جعل وظائفنا المخصصة تعمل أيضًا.

قم بإنشاء مكون إضافي من sil-extension-archetype


استنساخ النموذج الأصلي:

git clone https://alex1mmm@bitbucket.org/alex1mmm/sil-extension-archetype.git --branch v1 --single-branch

قم بتثبيت النموذج الأصلي في المستودع المحلي وقم بإنشاء مكون إضافي من هذا النموذج الأصلي. يمكن العثور على مزيد من التفاصيل حول كيفية القيام بذلك هنا .

إضافة خدمات SIL


من أجل جعل وظيفتنا محمولة بين الإصدارات المختلفة من Jira ، سنستخدم الخدمات التي تقدمها SIL. أولئك. سنقوم بالوكيل لإجراء مكالماتنا إلى Jira Java API عبر SIL Java Api.

ولكن كيف تعرف الخدمات التي تقدمها SIL؟

نقوم بتثبيت SIL ونذهب إلى العنوان التالي:

localhost : 2990 / jira / plugins / servlet / upm / osgi

سترى معلومات OSGI على جميع المكونات الإضافية في Jira:



سنجد المكون الإضافي في قائمة KATL Commons والخدمات المسجلة المفتوحة:



JMUserServices و JMProjectServices هي الخدمات التي تصدر Sil.

الآن نحن نعرف ما هي خدمات SIL المتاحة ، وباسم الخدمة يمكننا تخمين الغرض منها.

دعونا نرى الرمز في المكون الإضافي الذي تم إنشاؤه


الآن نحن نعرف ما هي الخدمات المتاحة لنا. دعونا نستخدمها في البرنامج المساعد لدينا.

BeanService.java


@Named
public class BeanService {
    @Getter
    private final KIssueService kIssueService;
    @Getter
    private final ClassLoaderService classLoaderService;
    @Getter
    private final CurrentUserHelper currentUserHelper;
    @Getter
    private final JMIssueSearchServices jmIssueSearchServices;
    @Getter
    private final UserHelper userHelper;
    @Getter
    private final JMIssueServices jmIssueServices;
    @Inject
    public BeanService(@ComponentImport KIssueService kIssueService,
                       @ComponentImport CurrentUserHelper currentUserHelper,
                       @ComponentImport JMIssueSearchServices     jmIssueSearchServices,
                       @ComponentImport UserHelper userHelper,
                       @ComponentImport JMIssueServices jmIssueServices,
                       ClassLoaderService classLoaderService) {
        this.kIssueService = kIssueService;
        this.classLoaderService = classLoaderService;
        this.currentUserHelper = currentUserHelper;
        this.jmIssueSearchServices = jmIssueSearchServices;
        this.userHelper = userHelper;
        this.jmIssueServices = jmIssueServices;
    }
}

تحتوي هذه الفئة على جميع الخدمات التي سنستخدمها لوظائفنا. أقوم بإنشاء فئة منفصلة من هذا القبيل حتى لا أكرر استدعاء الخدمات في كل وظيفة.

دعونا نلقي نظرة على هذه الخطوط:

@Getter
 private final KIssueService kIssueService;

حسنًاهذا هو التعليق التوضيحي لومبوك الذي ينشئ طريقة الحصول على خاصية kIssueService.

نقوم بإنشاء خصائص فئة لكل خدمة مستخدمة. بعد ذلك ، نحصل على هذه الخدمات من خلال المنشئ.

    public BeanService(@ComponentImport KIssueService kIssueService,
                       @ComponentImport CurrentUserHelper currentUserHelper,
                       @ComponentImport JMIssueSearchServices jmIssueSearchServices,
                       @ComponentImport UserHelper userHelper,
                       @ComponentImport JMIssueServices jmIssueServices,
                       ClassLoaderService classLoaderService) {
        this.kIssueService = kIssueService;
        this.classLoaderService = classLoaderService;
        this.currentUserHelper = currentUserHelper;
        this.jmIssueSearchServices = jmIssueSearchServices;
        this.userHelper = userHelper;
        this.jmIssueServices = jmIssueServices;
    }

منجز.

أضف BeanService bean إلى فئة ESLauncher وقم بتمرير هذه الحبة إلى وظائفنا:

/*   BeanService */
private final BeanService beanService;

@Inject
public ESLauncher(@ComponentImport EventPublisher eventPublisher,
                  PluginInfoService pluginInfoService,
                  @ComponentImport CommonPluginConfigurationService commonPluginConfigurationService,
                  @ComponentImport HostConfigurationProvider hostConfigurationProvider,
                  @ClasspathComponent PluginConfigurationServiceImpl pluginConfigurationService,
/*  BeanService */
                  BeanService beanService)
{
    super(eventPublisher, pluginInfoService, hostConfigurationProvider, pluginConfigurationService);

    log.error("eslauncher constructor");
    this.beanService = beanService;

}

@Override
public void doAtLaunch() {
    super.doAtLaunch();
    log.error("eslauncher doatlaunch");
    RoutineRegistry.register(new SayHello( beanService,"SayHello"));
    RoutineRegistry.register(new SayHello2( beanService,"SayHello2"));
    RoutineRegistry.register(new SayHello3( beanService,"SayHello3"));

}

الآن يمكننا استخدام BeanService في وظائفنا.

SayHello.java


في SayHello.java ، سنقوم بعمل وظيفة تقبل عنوان البريد الإلكتروني للمستخدم ، وتحقق من أن المستخدم الذي يقوم بتشغيل البرنامج النصي للمسؤول ، وحذف جميع التذاكر التي تم إنشاؤها بواسطة المستخدم باستخدام عنوان البريد الإلكتروني المرسل.

بالطبع ، يمكننا القيام بهذا المنطق دون كتابة وظيفتنا الخاصة. سيبدو رمز SIL كما يلي:

function deleteIssueForUser(string userEmail) {
  if (isUserInGroup("jira-administrators", currentUserKey())) {
    string[] issues = selectIssues("reporter = " + currentUserKey());
    for (string issue in issues) {
      deleteIssue(issue);
    }
  }
}

deleteIssueForUser("user@email.com");

لكنني أردت أن أقدم مثالاً صغيراً يوضح المبادئ الأساسية للعمل.

هنا نص الصف:

@Slf4j
public class SayHello extends AbstractSILRoutine<MutableString> {
    private static final SILType[][] types = {{ TypeInst.STRING }};
    private final BeanService beanService;

    public SayHello(BeanService beanService, String name) {
        super(beanService.getClassLoaderService().getPluginClassLoader(), name, types);
        this.beanService = beanService;
    }

    @Override
    public SILType<MutableString> getReturnType() {
        return TypeInst.STRING;
    }


    @Override
    protected SILValue<MutableString>  runRoutine(SILContext silContext, List<SILValue<?>> list)  {
        SILValue param = list.get(0);
        String userEmail = param.toStringValue();
        KIssueService kIssueService = beanService.getKIssueService();
        CurrentUserHelper currentUserHelper = beanService.getCurrentUserHelper();
        JMIssueSearchServices jmIssueSearchServices = beanService.getJmIssueSearchServices();
        UserHelper userHelper = beanService.getUserHelper();
        JMIssueServices jmIssueServices = beanService.getJmIssueServices();
        ApplicationUser requestedUser = userHelper.getUserByEmail(userEmail);

        if (currentUserHelper.isUserAdministrator()) {
            SearchService.ParseResult parseResult = jmIssueSearchServices.getSearchService().parseQuery(requestedUser, "reporter = " + requestedUser.getKey());
            List<Issue> issues = (List<Issue>) kIssueService.searchIssues(requestedUser, parseResult.getQuery());
            issues.stream().forEach(issue -> kIssueService.deindexIssue(jmIssueServices.getIssueManager().getIssueByCurrentKey(issue.getKey())));
        }
        return SILValueFactory.string( "issues deleted");

    }

    @Override
    public String getParams() {
        return "(userEmail)";
    }
}

نقوم بتطبيق المنطق في طريقة runRoutine:

    @Override
    protected SILValue<MutableString>  runRoutine(SILContext silContext, List<SILValue<?>> list)  {

/*     */

        SILValue param = list.get(0);
        String userEmail = param.toStringValue();

/*       SIL */

        KIssueService kIssueService = beanService.getKIssueService();
        CurrentUserHelper currentUserHelper = beanService.getCurrentUserHelper();
        JMIssueSearchServices jmIssueSearchServices = beanService.getJmIssueSearchServices();
        UserHelper userHelper = beanService.getUserHelper();
        JMIssueServices jmIssueServices = beanService.getJmIssueServices();

/*  SIL UserHelper,   ApplicationUser    */

        ApplicationUser requestedUser = userHelper.getUserByEmail(userEmail);

/*  SIL CurrentUserHelper,  ,     Jira */

        if (currentUserHelper.isUserAdministrator()) {

/*   SIL      JQL  */

            SearchService.ParseResult parseResult = jmIssueSearchServices.getSearchService().parseQuery(requestedUser, "reporter = " + requestedUser.getKey());
            List<Issue> issues = (List<Issue>) kIssueService.searchIssues(requestedUser, parseResult.getQuery());

/*    */

            issues.stream().forEach(issue -> kIssueService.deindexIssue(jmIssueServices.getIssueManager().getIssueByCurrentKey(issue.getKey())));
        }
        return SILValueFactory.string( "issues deleted");

    }

لقد قدمت تعليقات على الكود.

خدمة KIssueFieldsService


أود التحدث بشكل منفصل عن هذه الخدمة. في SIL ، في جميع الطرق التي تريد فيها نقل حقل مخصص ، يمكننا نقل إما اسم الحقل أو معرف الحقل بتنسيق customfield_NNNNN أو الاسم المستعار للحقل.

إذا لم نستخدم خدمات SIL ، فسيتعين علينا تنفيذ هذا المنطق بمفردنا. ولكن باستخدام خدمة KIssueFieldsService ، نستخدم هذه الوظيفة مع سطر واحد:

CustomField customField= this.kIssueFieldsService.getCustomField(customFieldName);

الآن أنت تعرف كيفية إنشاء وظائف SIL المحمولة بين إصدارات Jira.

All Articles