вторник, 25 сентября 2012 г.

Тренинги по Oracle Unified Method

Тренинги по Oracle Unified Method доступны на Oracle Learning Library.
На момент написания статьи доступно два уровня OUM: Все тренинги по OUM на Oracle Learning Library здесь.

Полезные ссылки:
  • Официальный блог здесь
  • Информация об сертификации Oracle Unified Method 5 Essentials (1Z0-568) здесь

понедельник, 17 сентября 2012 г.

Ошибка "internal xpath error" в oraext:query-database и вариант её решения

Ошибка:
При использовании XPath-функции oraext:query-database, если в запросе используются функции БД (например: select max(salary) from employee) возникает ошибка следующего вида:
 <bpelFault>  
  <faultType>0</faultType>  
  <subLanguageExecutionFault xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable">  
   <part name="summary">  
    <summary>An error occurs while processing the XPath expression; the  
         expression is oraext:query-database("select  
         max(salary) from employee",false(),false(),'jdbc/examplesDS').</summary>  
   </part>  
   <part name="detail">  
    <detail>XPath expression failed to execute. An error occurs while  
        processing the XPath expression; the expression is  
        oraext:query-database("select max(salary) from  
        employee",false(),false(),'jdbc/examplesDS'). The XPath  
        expression failed to execute; the reason was: internal xpath  
        error. Check the detailed root cause described in the exception  
        message text and verify that the XPath query is correct.</detail>  
   </part>  
   <part name="code">  
    <code>XPath expression failed to execute</code>  
   </part>  
  </subLanguageExecutionFault>  
 </bpelFault>  
А в логе managed-сервера:
 oracle.xml.sql.OracleXMLSQLException: Character ')' is not allowed in an XML tag name.  
     at oracle.xml.sql.core.OracleXMLConvert.getXML(OracleXMLConvert.java:1178)  
     at oracle.xml.sql.query.OracleXMLQuery.getXMLDOM(OracleXMLQuery.java:417)  
     at oracle.xml.sql.query.OracleXMLQuery.getXMLDOM(OracleXMLQuery.java:384)  
     at oracle.xml.sql.query.OracleXMLQuery.getXMLDOM(OracleXMLQuery.java:345)  
     at oracle.tip.pc.services.functions.ExtFunc.queryDatabase(ExtFunc.java:152)  
     at oracle.tip.pc.services.functions.ExtFuncFunction$QueryDatabaseFunction.call(ExtFuncFunction.java:359)
     ...
Причина:
XML SQL Utility (XSU) обрабатывает имя столбца как имя тега. В нашем случае имя столбца max(salary) рассматривается XSU как недопустимое имя тега, и происходит ошибка.

Вариант решения:
Необходимо добавить алиас для столбца в котором используются функции, т.е. в нашем случае:
 oraext:query-database("select max(salary) as salary from employee",
                                       false(),false(),'jdbc/examplesDS')  

суббота, 15 сентября 2012 г.

Хеширование SHA-1 и MD5 на PL/SQL и Java

  • Реализация на PL/SQL:
    • SHA-1:
       CREATE OR REPLACE  
        FUNCTION SHA1(plain_text VARCHAR2) RETURN VARCHAR2  
        AS  
        BEGIN  
         RETURN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(DBMS_CRYPTO.HASH (src => utl_i18n.string_to_raw (plain_text, 'AL32UTF8'), typ => DBMS_CRYPTO.HASH_SH1)));  
        END;  
      
    • MD5:
       CREATE OR REPLACE  
        FUNCTION MD5(plain_text VARCHAR2) RETURN VARCHAR2 IS  
        BEGIN  
         RETURN RAWTOHEX(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT => TL_RAW.CAST_TO_RAW(plain_text) ));  
        END;
      
  • Реализация на Java:
    import java.math.BigInteger;
    
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    public class CryptoUtils {
    
        private final static char[] ALPHABET =
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
    
        public static String sha1(String plain) {
            try {
                MessageDigest md = MessageDigest.getInstance("sha");
                md.update(plain.getBytes());
                byte[] digest = md.digest();
    
                return encode(digest);
                /* Альтернативные варианты:
                return javax.xml.bind.DatatypeConverter.printBase64Binary(digest);
                или
                return com.sun.org.apache.xml.internal.security.utils.Base64.encode(digest);
                */
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                return null;
            }
        }
    
        public static String md5(String raw) {
            try {
                MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(raw.getBytes(), 0, raw.length());
                return new BigInteger(1, md.digest()).toString(16);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                return null;
            }
        }
    
        public static String encode(byte[] buf) {
            int size = buf.length;
            char[] ar = new char[((size + 2) / 3) * 4];
            int a = 0;
            int i = 0;
            while (i < size) {
                byte b0 = buf[i++];
                byte b1 = (i < size) ? buf[i++] : 0;
                byte b2 = (i < size) ? buf[i++] : 0;
    
                int mask = 0x3F;
                ar[a++] = ALPHABET[(b0 >> 2) & mask];
                ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
                ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
                ar[a++] = ALPHABET[b2 & mask];
            }
            switch (size % 3) {
            case 1:
                ar[--a] = '=';
            case 2:
                ar[--a] = '=';
            }
            return new String(ar);
        }
    }