2017年4月23日日曜日

Spring Batchの戻り値をshellで取る

Spring Batchの戻り値を取れずにクソレベルにハマった


単純に、Shellからjavaコマンドでバッチを起動して、$?で取りたかっただけ
ExitStatusをグリグリ弄ったところでうまくいかない、結局、中のコード見たら、BatchStatusと何かの関連で決まるようなコードを見かけたので
module-context.xmlあたりにSimpleJvmExitCodeMapperのbeanを突っ込んで
 
   <!-- exitCodeMapper -->
   <bean class="org.springframework.batch.core.launch.support.SimpleJvmExitCodeMapper" id="exitCodeMapper"/>

@Autowiredした
public class KusoTasklet implements Tasklet, InitializingBean {
 @Autowired
 private SimpleJvmExitCodeMapper sm;
...

で、@Autowiredしたクラスあたりで、ExitStatus.COMPLETEDの値を書き換える
...
    protected void setResultCode(Integer result) {
        Map<String, Integer> exitCodeMap = new HashMap<String, Integer>();
        exitCodeMap.put(ExitStatus.COMPLETED.getExitCode(), result);
        sm.setMapping(exitCodeMap);
    }
...

やってみた


cuomo@ugui7 ~/workspace/batchkoi/target $ java -cp ./dependency/*:./spring-batch-kuso-2.0.0.CI-SNAPSHOT.jar org.springframework.batch.core.launch.support.CommandLineJobRunner launch-context.xml kusoGoodJob
2017-04-23 20:28:31,123 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - <Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2a33fae0: startup date [Sun Apr 23 20:28:31 JST 2017]; root of context hierarchy>
2017-04-23 20:28:31,147 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [launch-context.xml]>
2017-04-23 20:28:31,275 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/module-context.xml]>
...
...
...
2017-04-23 20:28:32,778 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@42eca56e: defining beans [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,eroUserServiceImpl,reader,writer,exampleConfiguration,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.batch.core.scope.internalStepScope,org.springframework.beans.factory.config.CustomEditorConfigurer,org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor,jobRepository,exitCodeMapper,step_kuso,kuso,kuso_Tasklet,step2,job1,fileDeletingTasklet,org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#1,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,eroUserMapper,dataSource,transactionManager,sqlSessionFactory,org.dozer.spring.DozerBeanMapperFactoryBean#0,jobLauncher]; root of factory hierarchy>
2017-04-23 20:28:32,780 INFO [org.dozer.jmx.JMXPlatformImpl] - <Unregistering existing Dozer JMX MBean [org.dozer.jmx:type=DozerAdminController].>
2017-04-23 20:28:32,780 INFO [org.dozer.jmx.JMXPlatformImpl] - <Unregistering existing Dozer JMX MBean [org.dozer.jmx:type=DozerStatisticsController].>
cuomo@ugui7 ~/workspace/batchkoi/target $ echo $?
99
cuomo@ugui7 ~/workspace/batchkoi/target $ 

resultへ任意の数字を仕込めばshellの戻り値になる


ググったら、ここに 書いてあるじゃないか。。。

なかのコード見てる暇あったら、みんなググロー、1日無駄になった...




2017年4月16日日曜日

gentoo+DjangoでOracle Database 11g につなぐ

DjangoからOracle DB 11gへつないでみる


べつにgentooじゃなくても繋げます、ただgentooでやりたかっただけです

DBコネクタcx_Oracleをいれる


mysql-pythonてきなDBコネクタcx_Oracleを入れておく、ebuild作っておきましたのどうぞ
ugui7 ~ # layman -a karky7
ugui7 ~ # emerge -pv dev-python/cx_oracle
lculating dependencies... done!
[ebuild  N f   ] dev-db/oracle-instantclient-basic-11.2.0.4::gentoo  ABI_X86="32 (64) (-x32)" 0 KiB
[ebuild  N    ~] dev-python/cx_oracle-5.3::karky7  USE="doc {-test}" PYTHON_TARGETS="python2_7 python3_4" 0 KiB
ugui7 ~ # emerge -pv dev-python/cx_oracle

最近の私のlaymanリポジトリは腐りつつあるのでご注意ください。ウケル

Djangoをセットアップ


Djangoは入れてあるものとします
settings.pyを書き換え
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'orcl', # SIDに指定するやつ
        'USER': 'ALCHU',
        'PASSWORD': 'IICHIKO20',
        'HOST': '192.168.253.13',
        'PORT': '1521'
    },
}

modelを作成


model.py
from __future__ import unicode_literals
from django.db import models

class Blogpost(models.Model):
    id = models.BigIntegerField(primary_key=True)
    title = models.TextField()
    authorid = models.ForeignKey('Person', db_column='authorId')  # Field name made lowercase.

    class Meta:
        db_table = 'BlogPost'


class Person(models.Model):
    id = models.BigIntegerField(primary_key=True)
    name = models.TextField()
    age = models.BigIntegerField(blank=True, null=True)
    regdate = models.DateTimeField(blank=True, null=True)

    class Meta:
        db_table = 'Person'

DBマイグレーションする


modelからテーブルを作成する
~/Code/django_skel $ ./manage.py makemigrations
~/Code/django_skel $ ./manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: staticfiles, messages
  Apply all migrations: admin, contenttypes, auth, app1, sessions
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying app1.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying sessions.0001_initial... OK
このあとPersonテーブルに適当にデータを突っ込む

開発サーバーで動かしてみる


~/Code/django_skel $ ./manage.py runserver


cx_Oracle入れるのに、oracle提供のバイナリが必要なのがちょっと面倒だけどとりあえずdjangoもOracle Databaseでもいけることが分かった今日この頃です。