I have the same problem that is described in this issue: Grant permission to queues to another schema in oracle.
But given permissions to the other user doesn't work at all.
My queue:
DBMS_AQADM.create_queue_table (
queue_table => 'event_queue_tab',
queue_payload_type => 't_event_queue_payload',
multiple_consumers => TRUE,
comment => 'Queue Table For Event Messages',
secure => false);
-- Create the event queue.
DBMS_AQADM.create_queue (queue_name => 'event_queue',
queue_table => 'event_queue_tab');
-- Start the event queue.
DBMS_AQADM.start_queue (queue_name => 'event_queue');
This queue as created using schema USER1. In this schema, I have a package pkg1 with a procedure when I call it, its enqueue:
PROCEDURE proc1
IS
PRAGMA AUTONOMOUS_TRANSACTION;
l_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
l_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
l_message_handle RAW (16);
l_queue_msg t_event_queue_payload;
BEGIN
l_queue_msg := t_event_queue_payload ('give_me_a_prod');
DBMS_AQ.enqueue (queue_name => 'event_queue',
enqueue_options => l_enqueue_options,
message_properties => l_message_properties,
payload => l_queue_msg,
msgid => l_message_handle);
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
SQLERRM || ' - ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END proc1;
I have a second schema USER2 who have privileges to execute pkg1 by a specific ROLE (ROLE1). But when he calls proc1, receive the next error:
ORA-24010: QUEUE USER2.EVENT_QUEUE does not exist - ORA-06512: at "SYS.DBMS_AQ", line 180
ORA-06512: at "USER1.PKG1", line 1808
I've executed this privilege command in USER1 but without success:
BEGIN
DBMS_AQADM.grant_queue_privilege (privilege => 'ALL',
queue_name => 'USER1.event_queue',
grantee => 'USER2',
grant_option => TRUE);
END;
I'm really starting to understand how Ad.Queues works. Am I missing something here? Thanks.
EDIT1:
After the grant given the privileges for this queue:
SELECT grantee,
owner,
name,
grantor,
enqueue_privilege,
dequeue_privilege
FROM queue_privileges
WHERE name = upper('event_queue');
ROLE1 USER1 EVENT_QUEUE USER1 1 1
USER2 USER1 EVENT_QUEUE USER1 1 1
Just a guess, does it have something to do with synonyms? Because the error message says USER2.QUEUE doesn't exist. Maybe its not able to touch User1 queue, because internally it is trying to find it in it's own schema? Try giving queue name in procedure as user1.event_queue.
What I mean is:
PROCEDURE proc1
IS
PRAGMA AUTONOMOUS_TRANSACTION;
l_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
l_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
l_message_handle RAW (16);
l_queue_msg t_event_queue_payload;
BEGIN
l_queue_msg := t_event_queue_payload ('give_me_a_prod');
DBMS_AQ.enqueue (queue_name => 'user1.event_queue',
enqueue_options => l_enqueue_options,
message_properties => l_message_properties,
payload => l_queue_msg,
msgid => l_message_handle);
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
SQLERRM || ' - ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END proc1;
Why I say so? Because when you are giving permission you are explicitly mentioning the schema USER1 before event_queue, and that procedure works. But not doing the same when using the enqueue procedure.
Related
I am new to the Oracle AQ process and have a few questions about the exception queue. Here's my scenario:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0
Create Table and Queue:
BEGIN
DBMS_AQADM.CREATE_QUEUE_TABLE (
QUEUE_TABLE =>'ADD_QUEUE_TABLE',
MULTIPLE_CONSUMERS => TRUE,
QUEUE_PAYLOAD_TYPE => 'ADD_OBJECT_TYPE');
DBMS_AQADM.CREATE_QUEUE (
QUEUE_NAME => 'ADD_QUEUE',
QUEUE_TABLE => 'ADD_QUEUE_TABLE',
max_retries => 6,
retry_delay => 1800);
DBMS_AQADM.START_QUEUE (QUEUE_NAME => 'ADD_QUEUE');
END;
/
To my understanding, it should retry dequeue for 6 times with delay of 30 mins and then send to exception queue. But in my case, it did send the messages to exception queue a lot before. I want your inputs to know if there is something I am missing or doing it wrong.
Enqueue:
CREATE PROCEDURE TXN_ENQUEUE_PROCEDURE (HN_TXN_SEQ IN NUMBER)
AS
ENQUEUE_OPTIONS DBMS_AQ.ENQUEUE_OPTIONS_T;
MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
MESSAGE_HANDLE RAW (16);
MESSAGE TXN_OBJECT_TYPE;
BEGIN
MESSAGE := TXN_OBJECT_TYPE (HN_TXN_SEQ);
DBMS_AQ.ENQUEUE (QUEUE_NAME => 'FILE_QUEUE',
ENQUEUE_OPTIONS => ENQUEUE_OPTIONS,
MESSAGE_PROPERTIES => MESSAGE_PROPERTIES,
PAYLOAD => MESSAGE,
MSGID => MESSAGE_HANDLE);
COMMIT;
END;
/
Dequeue:
CREATE OR REPLACE PROCEDURE TXN_DEQUEUE_PROCEDURE (
CONTEXT RAW,
REGINFO SYS.AQ$_REG_INFO,
DESCR SYS.AQ$_DESCRIPTOR,
PAYLOAD RAW,
PAYLOADL NUMBER)
AS
DEQUEUE_OPTIONS DBMS_AQ.DEQUEUE_OPTIONS_T;
MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
MESSAGE_HANDLE RAW (16);
MESSAGE TXN_OBJECT_TYPE;
BEGIN
DEQUEUE_OPTIONS.WAIT := DBMS_AQ.NO_WAIT;
DEQUEUE_OPTIONS.CONSUMER_NAME := 'MYSUBSCRIBER';
DEQUEUE_OPTIONS.NAVIGATION := DBMS_AQ.FIRST_MESSAGE;
DEQUEUE_OPTIONS.MSGID := DESCR.MSG_ID;
DEQUEUE_OPTIONS.CONSUMER_NAME := DESCR.CONSUMER_NAME;
LOOP
DBMS_AQ.DEQUEUE (QUEUE_NAME => DESCR.QUEUE_NAME,
DEQUEUE_OPTIONS => DEQUEUE_OPTIONS,
MESSAGE_PROPERTIES => MESSAGE_PROPERTIES,
PAYLOAD => MESSAGE,
MSGID => MESSAGE_HANDLE);
INSERT INTO MESSAGE_TABLE_SAMPLE VALUES (MESSAGE.HN_TXN_SEQ);
XYZ_PACKAGE.ABC_API (MESSAGE.HN_TXN_SEQ); ---- CALL API ----
COMMIT;
END LOOP;
END;
/
When I execute enqueue and if applications goes down or for any other reasons, the messages goes to exception queue. And if I dequeue from the exception queue, do I need to mention ( XYZ_PACKAGE.ABC_API (MESSAGE.HN_TXN_SEQ); ---- CALL API ----) within the dequeue process or it will be automatically called like normal queue dequeue process.
Exception queue :
EXECUTE DBMS_AQADM.START_QUEUE('AQ$_FILE_QUEUE_TABLE_E', false, true);
DECLARE
dequeue_options DBMS_AQ.dequeue_options_t;
message_properties DBMS_AQ.message_properties_t;
dq_msgid RAW(16);
payload RAW(1);
no_messages exception;
pragma exception_init (no_messages, -25263);
msg_count number(2);
cursor c_msg_ids is
select msg_id
from aq$FILE_QUEUE_TABLE
where queue = 'AQ$_FILE_QUEUE_TABLE_E';
BEGIN
dequeue_options.consumer_name := null;
dequeue_options.wait := DBMS_AQ.NO_WAIT;
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
dequeue_options.dequeue_mode := dbms_aq.remove_nodata;
For v_msg_id in c_msg_ids loop
dequeue_options.msgid := v_msg_id.msg_id;
msg_count := 0;
DBMS_AQ.DEQUEUE(queue_name => 'sys.AQ$_FILE_QUEUE_TABLE_E',
dequeue_options => dequeue_options,
message_properties => message_properties,
payload => payload,
msgid => dq_msgid);
dbms_output.put_line('Message id : '||v_msg_id.msg_id||' removed');
msg_count := msg_count + 1;
dequeue_options.msgid := null;
dequeue_options.navigation := DBMS_AQ.NEXT_MESSAGE;
END LOOP;
EXCEPTION
WHEN no_messages THEN
DBMS_OUTPUT.PUT_LINE ('No of Messages Removed: '||msg_count);
COMMIT;
END;
/
After executing the above one, it removes the messages from the exception queue. Do I need to mention ( XYZ_PACKAGE.ABC_API (MESSAGE.HN_TXN_SEQ); ---- CALL API ----) anywhere in between?
Is it better to execute exception queue or to have max_retries and with retry_delay?
If the messages move to exception queue, and if I run a query to dequeue them. Do they follow the same mechanism as in dequeue the normal queue and execute any additional apis that uses the message as input?
Thank you!
I've an asterisk pbx that manages some sip providers (a ISDN Patton) and some Voip providers.
I'm trying to use matching of CID in my dialplan as described here.
This is the relevant part of my dialplan, please note that this part of dialplan is included my extension.conf:
[patton];Calls from Patton
exten => 0219999999/_0031X.,1,Answer(0)
exten => 0219999999/_0031X.,n,Hangout()
exten => 0219999999,1,Answer(0)
exten => 0219999999,n,Goto(in_4,${EXTEN},1)
[in_4]
exten => 0219999999,1,Noop(Exten: ${EXTEN})
exten => 0219999999,n,Noop(CID: ${CALLERID(NUM)})
In short I want do something different when the CID of the caller cames from Netherlands.
Watching what happens in Asterisk CLI I see:
== Using SIP RTP CoS mark 5
-- Executing [0219999999#patton:1] Answer("SIP/patton-00000011", "0") in new stack
-- Executing [0219999999#patton:2] Goto("SIP/patton-00000011", "in_4,0219999999,1") in new stack
-- Goto (in_4,0219999999,1)
-- Executing [0219999999#in_4:1] NoOp("SIP/patton-00000011", "Exten: 0219999999") in new stack
-- Executing [0219999999#in_4:2] NoOp("SIP/patton-00000011", "Cid: 0031123456789") in new stack
So what I understand is that Asterisk don't apply the CID matching but I don't understand why, considering that if I print the CID it matches perfectly my expression.
Here is a section of my extensions.conf file that deals with inbound caller ID matching (from a PSTN line)
There might be another/better way to do this, but its been a working config for me since 1.4 and I'm now running 13.7 without any issues. (Individual numbers have been replaced with '#') - This is a simple dial plan.
This is used to catch anyone who send an 084 or 087 prefix, a couple of specific numbers and anything from 'international' or lazy system administrators 'UNAVAILABLE'
I've the same thing set up for SIP trunks as well so this should work across any channel type.
[from-pstn]
exten => s,1,Verbose(CLID From BT ${CALLERID(all)})
exten => s,2,GotoIf($[${CALLERID(num):0:3} = 087]?103:3)
exten => s,3,GotoIf($[${CALLERID(num):0:3} = 084]?103:4)
exten => s,4,GotoIf($[${CALLERID(num):0:11} = 07896######]?103:5)
exten => s,5,GotoIf($[${CALLERID(num):0:11} = 01494######]?103:6)
exten => s,6,GotoIf($["${CALLERID(name):0:13}" = "INTERNATIONAL"]?103:7)
exten => s,7,GotoIf($["${CALLERID(name):0:11}" = "UNAVAILABLE"]?103:8)
exten => s,8,GotoIf($[${CALLERID(num):0:10} = 020315####]?103:9)
exten => s,103,Answer
exten => s,104,Wait(1)
exten => s,105,Playtones(info)
exten => s,106,Wait(7)
exten => s,107,Hangup
exten => s,9,Goto(internal-ext,5800,1)
You would want something like;
[from-yourtrunk]
exten => s,1,Verbose(CLID From <yourtrunk> ${CALLERID(all)})
exten => s,2,GotoIf($[${CALLERID(num):0:4} = 0031]?103:3)
exten => s,103,<do something with the call that matches the CLI>
exten => s,3,Goto(<your-internal-ext>,<number>,1)
Something to keep in mind - if you handle inbound caller ID that could start 0031 but its not a call from .nl then you would need to apply some additional patten matching to the 2nd line to enforce a minimum number of digits (for example) otherwise that will match any call that comes in with a CLI of 0031...............................
If you need any more explanation, or I've got the wrong end of the stick just add a comment to this answer.
There can be non zero probability, that cid is go in other format(use Verbose or Noop command to show real cid)
Also in this case any dialplan can work if cid match
Asterisk not select "most matching" dialplan. Insead it select FIRST matching dialplan.
You can use different contexts and include directive to control matching. See examples in extensions.conf.sample
-- Executing [19#test:1] Answer("SIP/test2-0000821a", "") in new stack
-- Executing [19#test:2] Set("SIP/test2-0000821a", "CALLERID(num)=0031123456789") in new stack
-- Executing [19#test:3] Goto("SIP/test2-0000821a", "patton,0219999999,1") in new stack
-- Goto (patton,0219999999,1)
-- Executing [0219999999#patton:1] Answer("SIP/test2-0000821a", "0") in new stack
[Feb 10 08:26:09] WARNING[15817][C-00008bfe]: pbx.c:4869 pbx_extension_helper: No application 'Hangout' for extension (patton, 0219999999, 2)
== Spawn extension (patton, 0219999999, 2) exited non-zero on 'SIP/test2-0000821a'
[Feb 10 08:26:45] NOTICE[1499]: chan_sip.c:28210 handle_request_register: Registration from '"407" <sip:407#78.47.159.180:5060>' failed for '221.144.172.3:5083' - Wrong password
pro-sip*CLI> dialplan show pa
park-dial park-hints park-orphan-routing park-return-routing parkedcalls parkedcallstimeout
patton
pro-sip*CLI> dialplan show patton
[ Context 'patton' created by 'pbx_config' ]
'0219999999' (CID match '_0031X.') => 1. Answer(0) [pbx_config]
2. Hangout() [pbx_config]
'0219999999' => 1. Answer(0) [pbx_config]
2. Goto(in_4,${EXTEN},1)
[pbx_config] pro-sip*CLI> core show applications like Hang
-= Matching Asterisk Applications =-
ChangeMonitor: Change monitoring filename of a channel.
Hangup: Hang up the calling channel.
HangupCauseClear: Clears hangup cause information from the channel that is available through HANGUPCAUSE.
SoftHangup: Hangs up the requested channel.
-= 4 Applications Matching =- pro-sip*CLI>
Addon2(please note, debug is OFFTOPIC on SO)
-- Executing [0219999999#patton:1] NoOp("SIP/test2-0000821c", "cid match") in new stack
-- Executing [0219999999#patton:2] Answer("SIP/test2-0000821c", "0") in new stack
[Feb 10 08:32:18] WARNING[15826][C-00008c00]: pbx.c:4869 pbx_extension_helper: No application 'Hangout' for extension (patton, 0219999999, 3)
== Spawn extension (patton, 0219999999, 3) exited non-zero on 'SIP/test2-0000821c'
pro-sip*CLI> dialplan show pa
park-dial park-hints park-orphan-routing park-return-routing parkedcalls parkedcallstimeout
patton
pro-sip*CLI> dialplan show patton
[ Context 'patton' created by 'pbx_config' ]
'0219999999' (CID match '_0031X.') => 1. Noop(cid match) [pbx_config]
2. Answer(0) [pbx_config]
3. Hangout() [pbx_config]
'0219999999' => 1. NOOP(CIDNOTMATCH) [pbx_config]
2. Answer(0) [pbx_config]
3. Goto(in_4,${EXTEN},1) [pbx_config]
I have this piece of code:
BEGIN
DBMS_SCHEDULER.DROP_JOB (
job_name => 'LOANSBUILD.LOANSNEWYORKCLOSE');
END;
/
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => '***.LOANSNEWYORKCLOSE',
job_type => 'PLSQL_BLOCK',
job_action => 'begin loans_schedule_job.loans_close(TRUNC(SYSDATE), ''N''); end;',
start_date => '15-NOV-08 12.00.00.000000000 AM AMERICA/NEW_YORK',
repeat_interval => 'FREQ=WEEKLY;BYDAY=MON,TUE,WED,THU,FRI;BYHOUR=16;BYMINUTE=0;BYSECOND=0',
auto_drop => FALSE,
job_class => 'DEFAULT_JOB_CLASS',
enabled => TRUE,
comments => 'Test.'
);
END;
/
exit;
When the above is executed from an environment which has oracle sql client 10.2 installed , this goes fine but when the same is executed fron an environment that has 11.2 client installed, this fails as below:
BEGIN
*
ERROR at line 1:
ORA-01830: date format picture ends before converting entire input string
ORA-06512: at line 2
The variable nls_date_format is set to 'DD-MON-RR' in the 10.2 environment and set to 'YYYY-MM-DD HH24:MI:SS' in the 11.2 env.
As this was getting compiled for 10.2 env, I updated nls_lang_date in the 11.2 env as well to make it 'DD-MON-RR' but even after that I get the same error. Is there anything else I should be setting.
Please note that I am sysadmin and as this code is getting compiled on of the server, my job is to ensure that it does on others as well. Which also means that I do not have permissions to update code.
According to the CREATE_JOB Procedure documentation, the parameter start_date must be of type TIMESTAMP WITH TIME ZONE.
In your PL/SQL code you are instead passing a string thus relying on implicit conversion.
You could instead use an explicit conversion to the TIMESTAMP WITH TIME ZONE data type such as:
TO_TIMESTAMP_TZ('15-NOV-08 12.00.00.000000000 AM AMERICA/NEW_YORK', 'DD-MON-RR HH:MI:SS.FF AM TZR')
I have created a web service using ASP.NET.
I tried to access this url from a PL/sql program through UTL_DBWS package. After execution i am receiving below error:
ORA-29532: Java call terminated by uncaught Java exception: port: {http://tempuri.org/}Service1Soap
does not contain operation: Envelope
Can any one of you please tell what steps of configuration I am missing.
I really apprcite your help.
Oracle procedure to call to asp.net service is :
create or replace procedure check_dbws
AS
l_service UTL_DBWS.service;
l_call UTL_DBWS.call;
l_wsdl_url VARCHAR2(32767);
l_namespace VARCHAR2(32767);
l_service_qname UTL_DBWS.qname;
l_port_qname UTL_DBWS.qname;
l_operation_qname UTL_DBWS.qname;
l_xmltype_in SYS.XMLTYPE;
l_xmltype_out SYS.XMLTYPE;
p_fault_node xmltype;
l_return NUMBER;
l_int_type utl_dbws.qname;
l_string_type utl_dbws.QNAME;
BEGIN
l_wsdl_url := 'http://localhost/TestWebService/Service1.asmx?wsdl';
l_namespace := 'http://tempuri.org/';
l_service_qname := UTL_DBWS.to_qname(l_namespace, 'Service1');
l_port_qname := UTL_DBWS.to_qname(l_namespace, 'Service1Soap');
l_operation_qname := UTL_DBWS.to_qname(l_namespace, 'DBConnect');
l_service := UTL_DBWS.create_service (
wsdl_document_location => URIFACTORY.getURI(l_wsdl_url),
service_name => l_service_qname);
l_call := UTL_DBWS.create_call (
service_handle => l_service,
port_name => l_port_qname,
operation_name => l_operation_qname);
utl_dbws.set_property (l_call,'SOAPACTION_USE','TRUE');
utl_dbws.set_property (l_call,'SOAPACTION_URI', 'DBConnect');
utl_dbws.set_property(l_call,'ENCODINGSTYLE_URI', 'http://schemas.xmlsoap.org/soap/encoding/');
utl_dbws.set_property(l_call,'OPERATION_STYLE', 'document');
l_string_type :=utl_dbws.to_qname('http://www.w3.org/2001/xmlschema','String');
utl_dbws.add_parameter(l_call,'Request',l_string_type,'ParameterMode.IN');
utl_dbws.set_return_type(l_call,l_string_type);
l_xmltype_in:=sys.xmltype('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v002="http://tempuri.org/DBConnect">
<soapenv:Header/>
<soapenv:Body>
<DBConnect>
<Name>Test</Name>
<DBConnect>
</soapenv:Body>
</soapenv:Envelope>');
l_xmltype_out := UTL_DBWS.invoke (call_handle => l_call,,request => l_xmltype_in);
p_fault_node := l_xmltype_out.extract('//soap:Fault', 'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/');
if (p_fault_node is not null) then
dbms_output.put_line(p_fault_node.getclobval());
l_return:=2;
elsif l_xmltype_out is not null then
dbms_output.put_line(l_xmltype_out.getclobval());
l_return:=1;
else
dbms_output.put_line('errorin fault'||sqlerrm);
l_return:=0;
end if;
UTL_DBWS.release_call (call_handle => l_call);
UTL_DBWS.release_service (service_handle => l_service);
dbms_output.put_line(l_result.AccessVarchar2);
END;
have a look at my answer here; you may not have all the Java classes required to get UTL_DBWS to work. And, per my answer there, I'll reiterate, I found it much easier to use UTL_HTTP than UTL_DBWS and continue to use UTL_HTTP since I ran into so many limitations and issues with UTL_DBWS.
I am trying to implement a complex dialplan that requires interaction with the user. Based on this interaction, the dialplan jumps to another part. Some sample code is given below:
[test]
;This is a test.
exten => 0,n(qa1),NoOp()
exten => 0,1,Verbose(1, "This is a test")
exten => 0,n,Set(USER_ANSWER=0)
exten => 0,n,Read(USER_ANSWER,,1,,2,10)
exten => 0,n,Verbose(1, "User keyed in ${USER_ANSWER}")
exten => 0,n,GotoIf($[$["${USER_ANSWER}"="1"] | $["${USER_ANSWER}"="2"]]?eval1:qa1)
exten => 0,n,Verbose(1, "User keyed in ${USER_ANSWER}")
exten => 0,n(eval),NoOp()
...
On running the above code, asterisk hangs up after evaluating the GotoIf condition above. The error messages are as follows:
-- User entered '1'
-- Executing [0#test:19] Verbose("DAHDI/13-1", "1, "User keyed in 1"") in new stack
"User keyed in 1"
-- Executing [0#test:20] GotoIf("DAHDI/13-1", "1?eval1:qa1") in new stack
-- Goto (test,0,21)
-- Executing [0#test:21] NoOp("DAHDI/13-1", "") in new stack
[Jan 25 10:47:48] WARNING[29738]: pbx.c:3677 pbx_extension_helper: No application 'If' for extension (test, 0, 22)
My questions are:
What does that error message mean?
How can I correct it so it works?
The GotoIf is invoked correctly. The label eval1 has If statements following it. Asterisk does not have If statements. Replacing the If statements with ExecIf did the trick. One can figure out what commands are available by typing, at the Asterisk CLI prompt, the following command:
core show application <command name here>
If the above command returns an output, then that command is available, else not.