Recurring Schedule in Oracle Fusion BI Publisher Reports via SOAP - oracle

I am attempting to use xmlpserver/services/v2/ScheduleService of the Oracle BI Publisher to schedule a recurring job. Unfortunately, with no examples and no luck with try and error method, I can't schedule a report in a recurring manner, I manage, however, to execute it once.
I want to understand what tu put in recurrenceExpression, recurrenceExpressionType, repeatCount, repeatInterval, startDate to make it work. I am looking for a daily execution at n o'clock.
Here is the XML :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://xmlns.oracle.com/oxp/service/v2">
<soapenv:Header/>
<soapenv:Body>
<v2:scheduleReport>
<v2:scheduleRequest>
<v2:deliveryChannels>
<v2:ftpOptions>
<v2:item>
<v2:ftpServerName>?</v2:ftpServerName>
<v2:remoteFile>?</v2:remoteFile>
<v2:sftpOption>?</v2:sftpOption>
</v2:item>
</v2:ftpOptions>
</v2:deliveryChannels>
<v2:jobLocale>en_US</v2:jobLocale>
<v2:jobTZ>Etc/UTC</v2:jobTZ>
<v2:mergeOutputOption>false</v2:mergeOutputOption>
<v2:notificationTo>?</v2:notificationTo>
<v2:notifyWhenFailed>true</v2:notifyWhenFailed>
<v2:notifyWhenSkipped>true</v2:notifyWhenSkipped>
<v2:notifyWhenWarning>true</v2:notifyWhenWarning>
<v2:recurrenceExpression>?</v2:recurrenceExpression>
<v2:recurrenceExpressionType>cron</v2:recurrenceExpressionType>
<v2:repeatCount>1</v2:repeatCount>
<v2:repeatInterval>86400</v2:repeatInterval>
<v2:reportRequest>
<v2:attributeCalendar>Gregorian</v2:attributeCalendar>
<v2:attributeFormat>Text</v2:attributeFormat>
<v2:attributeLocale>fr</v2:attributeLocale>
<v2:reportAbsolutePath>?</v2:reportAbsolutePath>
<v2:sizeOfDataChunkDownload>-1</v2:sizeOfDataChunkDownload>
</v2:reportRequest>
<v2:saveDataOption>true</v2:saveDataOption>
<v2:saveOutputOption>true</v2:saveOutputOption>
<!--Optional:-->
<v2:startDate>2022-09-23T19:07:00Z</v2:startDate>
<v2:userJobName>test_REPORT</v2:userJobName>
</v2:scheduleRequest>
<v2:userID>?</v2:userID>
<v2:password>?</v2:password>
</v2:scheduleReport>
</soapenv:Body>
</soapenv:Envelope>
Many fields in the example are blank to protect sensitive data.
Here is the link to the documentation: https://docs.oracle.com/cd/E28280_01/bi.1111/e22259/scheduleservice.htm#BIPDV323

About reccurence and cron expressions see this page: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm
or this one: https://docs.aws.amazon.com/glue/latest/dg/monitor-data-warehouse-schedule.html
All I can offer is a working sample soap message (BI Publisher 12.2.1.4.0) scheduling the report on some start date with two parameters. BIP is quite sensitive to the start date format. Repeat count is an integer as well as repeat interval (seconds) and there is no questions there.
<?xml version="1.0" encoding="utf-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap-env:Body>
<ns0:scheduleReport xmlns:ns0="http://xmlns.oracle.com/oxp/service/v2">
<ns0:scheduleRequest>
<ns0:dataModelUrl>http://full_url_to_datamodel/YourDataModelName.xdm</ns0:dataModelUrl>
<ns0:jobLocale>hr-Hr</ns0:jobLocale>
<ns0:repeatCount>1</ns0:repeatCount>
<ns0:reportRequest>
<ns0:attributeCalendar>Gregorian</ns0:attributeCalendar>
<ns0:attributeFormat>pdf</ns0:attributeFormat>
<ns0:attributeLocale>hr-Hr</ns0:attributeLocale>
<ns0:attributeTemplate>YourTemplateName.rtf</ns0:attributeTemplate>
<ns0:parameterNameValues>
<ns0:listOfParamNameValues>
<ns0:item>
<ns0:name>PARAM_1_NAME</ns0:name>
<ns0:values>
<ns0:item>PARAM_1_VALUE</ns0:item>
</ns0:values>
</ns0:item>
<ns0:item>
<ns0:name>PARAM_2_NAME</ns0:name>
<ns0:values>
<ns0:item>PARAM_2_VALUE</ns0:item>
</ns0:values>
</ns0:item>
</ns0:listOfParamNameValues>
</ns0:parameterNameValues>
<ns0:reportAbsolutePath>/~user/FolderPath/ToYour/Report/YourReportName.xdo</ns0:reportAbsolutePath>
</ns0:reportRequest>
<ns0:scheduleBurstingOption>True</ns0:scheduleBurstingOption>
<ns0:startDate>2020-10-08T09:00:00+02:00</ns0:startDate>
<ns0:userJobName>YOUR_JOB_NAME_2020-09_1</ns0:userJobName>
</ns0:scheduleRequest>
<ns0:userID>your_username</ns0:userID>
<ns0:password>your_password</ns0:password>
</ns0:scheduleReport>
</soap-env:Body>
</soap-env:Envelope>
It took me some time to collect it all from the docs. Almost all of the types declared in wsdl are complex so I had to crawl through the docs to make it work. First thing that helped was extracting methods and types from the wsdl file of Schedule Service.
Here are the methods and types extracted from the wsdl.
/*
Service ( ScheduleService ) tns="http://xmlns.oracle.com/oxp/service/v2"
Prefixes (1)
ns0 = "http://xmlns.oracle.com/oxp/service/v2"
Ports (1):
(ScheduleService)
Methods (41):
cancelSchedule(xs:string jobInstanceID, xs:string userID, xs:string password, )
cancelScheduleInSession(xs:string jobInstanceID, xs:string bipSessionToken, )
deleteJobHistory(xs:string instanceJobID, xs:string userID, xs:string password, )
deleteJobHistoryInSession(xs:string instanceJobID, xs:string bipSessionToken, )
deleteSchedule(xs:string jobInstanceID, xs:string userID, xs:string password, )
deleteScheduleInSession(xs:string jobInstanceID, xs:string bipSessionToken, )
deliveryService(DeliveryRequest deliveryRequest, xs:string userID, xs:string password, )
deliveryServiceInSession(DeliveryRequest deliveryRequest, xs:string bipSessionToken, )
downloadDocumentData(xs:string jobOutputID, xs:string userID, xs:string password, )
downloadDocumentDataInSession(xs:string jobOutputID, xs:string bipSessionToken, )
downloadXMLData(xs:string jobInstanceID, xs:string userID, xs:string password, )
downloadXMLDataInSession(xs:string jobInstanceID, xs:string bipSessionToken, )
getAllJobInstanceIDs(xs:string submittedJobId, xs:string userID, xs:string password, )
getAllScheduledReport(JobFilterProperties filter, xs:int beginIdx, xs:string userID, xs:string password, )
getAllScheduledReportHistory(JobFilterProperties filter, xs:int beginIdx, xs:string userID, xs:string password, )
getAllScheduledReportHistoryInSession(JobFilterProperties filter, xs:int beginIdx, xs:string bipSessionToken, )
getAllScheduledReportInSession(JobFilterProperties filter, xs:int beginIdx, xs:string bipSessionToken, )
getDeliveryServiceDefinition(xs:string userID, xs:string password, )
getDeliveryServiceDefinitionInSession(xs:string bipSessionToken, )
getDocumentData(xs:string jobOutputID, xs:string userID, xs:string password, )
getDocumentDataInSession(xs:string jobOutputID, xs:string bipSessionToken, )
getScheduledJobInfo(xs:string jobInstanceID, xs:string userID, xs:string password, )
getScheduledJobInfoInSession(xs:string jobInstanceID, xs:string bipSessionToken, )
getScheduledReportDeliveryInfo(xs:string jobOutputID, xs:string userID, xs:string password, )
getScheduledReportDeliveryInfoInSession(xs:string jobOutputID, xs:string bipSessionToken, )
getScheduledReportOutputInfo(xs:string jobInstanceID, xs:string userID, xs:string password, )
getScheduledReportOutputInfoInSession(xs:string jobInstanceID, xs:string bipSessionToken, )
getScheduledReportStatus(xs:string scheduledJobID, xs:string userID, xs:string password, )
getScheduledReportStatusInSession(xs:string scheduledJobID, xs:string bipSessionToken, )
getXMLData(xs:string jobInstanceID, xs:string userID, xs:string password, )
getXMLDataInSession(xs:string jobInstanceID, xs:string bipSessionToken, )
purgeJobHistory(xs:string instanceJobID, xs:string userID, xs:string password, )
purgeJobHistoryInSession(xs:string instanceJobID, xs:string bipSessionToken, )
resendScheduledReport(xs:string outputJobID, xs:string userID, xs:string password, )
resendScheduledReportInSession(xs:string outputJobID, xs:string bipSessionToken, )
resumeSchedule(xs:string jobInstanceID, xs:string userID, xs:string password, )
resumeScheduleInSession(xs:string jobInstanceID, xs:string bipSessionToken, )
scheduleReport(ScheduleRequest scheduleRequest, xs:string userID, xs:string password, )
scheduleReportInSession(ScheduleRequest scheduleRequest, xs:string bipSessionToken, )
suspendSchedule(xs:string jobInstanceID, xs:string userID, xs:string password, )
suspendScheduleInSession(xs:string jobInstanceID, xs:string bipSessionToken, )
Types (44):
AccessDeniedException
ArrayOfEMailDeliveryOption
ArrayOfFTPDeliveryOption
ArrayOfFaxDeliveryOption
ArrayOfJobInfo
ArrayOfJobOutput
ArrayOfJobOutputDelivery
ArrayOfLocalDeliveryOption
ArrayOfMetaData
ArrayOfParamNameValue
ArrayOfPrintDeliveryOption
ArrayOfString
ArrayOfWCCDeliveryOption
ArrayOfWebDAVDeliveryOption
BIPDataSource
DeliveryChannels
DeliveryRequest
DeliveryServiceDefinition
EMailDeliveryOption
FTPDeliveryOption
FaxDeliveryOption
FileDataSource
InvalidParametersException
JDBCDataSource
JobDetail
JobFilterProperties
JobInfo
JobInfosList
JobOutput
JobOutputDelivery
JobOutputDeliverysList
JobOutputsList
JobStatus
LocalDeliveryOption
MetaData
MetaDataList
OperationFailedException
ParamNameValue
ParamNameValues
PrintDeliveryOption
ReportRequest
ScheduleRequest
WCCDeliveryOption
WebDAVDeliveryOption
*/

Related

Spring Boot Content Type Error even when specified in Kotlin

I have an issue in Spring Boot with Kotlin
I have a function that accepts all major Content Types as defined below:
#PostMapping(
value = ["/users/new"],
consumes = [
MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE,
MediaType.MULTIPART_FORM_DATA_VALUE,
MediaType.APPLICATION_FORM_URLENCODED_VALUE]
)
fun registerNewUser(
#RequestHeader("X-Forward-For") ipAddress: String?,
newUser: NewUser,
request: HttpServletRequest
): ResponseEntity<ObjectNode> {
var realIPAddress = ipAddress
if (realIPAddress == null) {
realIPAddress = request.remoteAddr
}
return userService.registerUser(realIPAddress!!, newUser)
}
Here is how my NewUser class is defined in kotlin
data class NewUser(val email: String?, val password: String?)
Here is how I am doing the check in the registration function
if (!StringUtils.hasText(newUser.email)) {
return responseHandler.errorResponse(
HttpStatus.BAD_REQUEST,
"Please provide an email address"
)
}
Now when I sent a post request with postman and even axios I keep getting the error as shown in the screenshot below
That error message should only be displayed if email address is not provided. But as you can see clearly, the email address is provided in the JSON Payload.
What could be wrong?
Note: This works when the Content-Type is application/x-www-form-urlencoded but doesn't work when the Content-Type is application/json
put #RequestBody before newUser parameter to specify that input should be inside http body part. by default function parameters in spring are considered to be url parameters which can be further clarified with #RequestParam.
there are 2 ways to insert request parameters into http request. one is to attach request parameters to end of the url and the other is to put in http body with application/x-www-form-urlencoded as the content-type.

How to add AuthHeader on gowsdl

I am integrating soap service with use gowsdl library.
I can't create auth header like this;
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header>
<tem:AuthHeader>
<!--Optional:-->
<tem:UserName>?</tem:UserName>
<!--Optional:-->
<tem:Password>?</tem:Password>
</tem:AuthHeader>
</soapenv:Header>
<soapenv:Body>
</soapenv:Body>
</soapenv:Envelope>
I am using code generated by gowsdl
I will explain shortly;
AuthHeader in service.go
type AuthHeader struct {
UserName string `xml:"UserName,omitempty" json:"UserName,omitempty"`
Password string `xml:"Password,omitempty" json:"Password,omitempty"`
}
and I am using like this
authHeader := service.AuthHeader{
Password: Password,
UserName: Username,
}
header := struct {
AuthHeader service.AuthHeader `xml:"AuthHeader,omitempty" json:"AuthHeader,omitempty"`
}{
AuthHeader:authHeader,
}
And adding header like this;
soapClient := soap.NewClient(Url)
soapClient.AddHeader(header)
but it is not working! How can I solve this problem?
From the gowsdl package's example.go why not set the auth headers like so:
client := soap.NewClient(
Url,
soap.WithBasicAuth("usr", "psw"),
)

Django Rest Framework JWT Auth

I have an issue posting/getting any requests after JWT login. (I am using the djangorestframework-jwt library) The user succesfully logs in, the app returns the json token but when I use this token for the next requests I get
{
"detail": "Authentication credentials were not provided."
}
settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
JWT_AUTH = {
'JWT_ALLOW_REFRESH': True,
'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=1),
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
}
Login View
def post(self, request, format=None):
if not request.data:
return Response({'Error': "Please provide username/password"}, status=status.HTTP_400_BAD_REQUEST)
username = request.data['username']
password = request.data['password']
try:
user = User.objects.get(email=username, password=password)
except User.DoesNotExist:
return Response({'Error': "Invalid username/password"}, status=status.HTTP_400_BAD_REQUEST)
if user:
payload = {
'id': user.id,
'email': user.email,
'first_name': user.first_name
}
jwt_token = jwt.encode(payload, "SECRET_KEY") # to be changed
return Response({'token': jwt_token}, status=status.HTTP_200_OK)
and then every other view contains
authentication_class = (JSONWebTokenAuthentication,)
permission_classes = (IsAuthenticated,)
I have tested both with postman and curl but I get the same error. Not sure if there is an error with the header format or if there is smth else I'm missing. Any help would be greatly appreciated!
EDIT:
I have changed my settings to
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
but now I get that
{
"detail": "Error decoding signature."
}
EDIT: I think the issue is that jwt_token = jwt.encode(payload, 'SECRET_KEY') might return a token that is not recognised...if i use the token generated by obtain_jwt_token then i can query any endpoint. Could anyone explain this?
EDIT: so I changed to jwt_token = jwt_encode_handler(payload) and the settings file contains the JWT_SECRET_KEY (when i verify the token i receive after login on jwt, it is indeed the right token with the right payload and secret) but it's still not recognised "detail": "Invalid signature."
I managed to solve my problem. When authenticating a user I was checking against a custom user table that I had created earlier, which was different from the django's auth_user table. I changed django's settings to use my custom users table and then using the token from the authentication worked for the other requests as well.
AUTH_USER_MODEL = 'main.User'
The problem is you encode the JWT by using "SECRET KEY" and decode using another key. The default secret key used by jwt is settings.SECRET_KEY. But when you create a custom jwt token you uses a string as secret "SECRET_KEY". But you use default jwt verification which automatically uses settings.SECRET_KEY.
So add 'JWT_SECRET_KEY': settings.SECRET_KEY, in to your JWT settings and use this key for encode and decode.
Ex:
jwt_token = jwt.encode(payload, settings.SECRET_KEY)
or you can override the jwt verification and create your own.

form data is not getting posted to spring controller

Form data:
form dat from UI developer tools
user.username:SS
user.email:SGFG#GMAIL.COM
user.firstName:WWW
user.lastName:FF
ext-gen1170:ENV_DEV
ext-gen1171:false
ext-gen1172:false
user.password:
userGroupPermissions:[{"userName":"SS","groupName":"ENV_DEV","permission":"*"}]
Web.xml for the dispatcher servlet:
<servlet-mapping>
<servlet-name>user</servlet-name>
<url-pattern>/spring/</url-pattern>
</servlet-mapping>
Controller:
#RequestMapping(value ="/createUser/", method = RequestMethod.POST)
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
#ResponseBody
public String createUser(#RequestParam(value = "user.username", required = true) String username,
#RequestParam(value = "user.email", required = true) String email,
#RequestParam(value = "user.firstName", required = true) String firstName,
#RequestParam(value = "user.lastName", required = true) String lastName,
#RequestParam(value = "userGroupPermissions", required = true) UserGroupPermission userGroupPermissions,
#RequestParam(value = "password", required = false) String password) throws IOException {
Above details will be added to handle the request
There are no errors in console but the breakpoint is not hit when I keep the break point in controller.
I am getting 404 for this code.
Extjs:
var url = '/spring/createUser';
There are two ways to resolve this -- change the way you are sending parameters to Java or change the way you are receiving parameters.
Just change Java
To keep things simple you should change Java.
GET requests should use #RequestParam arguments in Spring controllers in a way you specified.
POST/PUT requests should use #RequestBody argument in Spring controllers.
So the Spring controller should look like this:
#RequestMapping(value ="/createUser/", method = RequestMethod.POST)
#ResponseBody
public String createUser(#RequestBody UserParams params)
Obviously if you need the #Transactional part you should also leave it.
Sending various requests with ExtJS
Here are some examples on how to use Ext.Ajax.request to send various types of requests.
I've used Polish in values so you can also see how encoding of UTF-8 text works.
Query string
Sending in query string means things get encoded directly in URL after ?. E.g. /test?firstName=Imi%C4%99&lastName=Nazwisko.
// (Java/Spring can get this with `#RequestParam`)
Ext.Ajax.request({
url: '/test',
method: 'GET',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Form data
This is used when sending forms in a standard way. Things get encoded in the body of the request, but the format is actually the same as for the query string (e.g. firstName=Imi%C4%99&lastName=Nazwisko).
// (Java/Spring can get this with `#RequestBody`)
Ext.Ajax.request({
url: '/test',
method: 'PUT',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Request payload
This is a JSON communication. Things get encoded in the body of the request, but in a JSON format (e.g. {"firstName":"Imi\u0119","lastName":"Nazwisko"}).
// (Java/Spring can get this with `#RequestBody`)
Ext.Ajax.request({
url: '/test',
method: 'PUT',
jsonData: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Query string in PUT/POST request
You can trick ExtJS to pass parameters in the URL rather then request body. When both params and jsonData are present in the Ext.Ajax.request one of them has to be put in the URL.
So to pass params in the query string use this:
Ext.Ajax.request({
url: '/test',
method: 'PUT',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
},
jsonData: {}
});
Note the empty jsonData. This will be encoded in request body as {} and can simply be omitted on the receiving end. In this case Java/Spring.
So this way you would receive all params as #RequestParam arguments in your Spring controller.

how to handle token authentication in Angular Dart?

First time dealing with a SPA. I have a back-end restful service that returns a token when a user signs in. I know I am supposed to send the token through the headers in each request so I was thinking in saving the token in a file and create a service or a class that loads the token in every component but I don't know if this is a good approach as I can't find documentation for Angular Dart about this.
I saved the Token first in localStorage as Tobe O suggested:
Future login(username, password) async {
String url = 'http://127.0.0.1:8000/auth/login/';
var response =
await _client.post(url, body: {'username': username, 'password': password});
Map mapped_response = _decoder.convert(response.body);
window.localStorage.addAll({"token": mapped_response["key"]});
}
But still I was receiving 401 responses when I tried to get user information, this was the function:
Future check_authentification () async {
String _headers_key = "Authorization";
String _headers_value = "Token "+window.localStorage["token"];
var response = await _client.get("http://127.0.0.1:8000/auth/user/", headers: {_headers_key: _headers_value});
user_data = _decoder.convert(response.body);
response_status = response.statusCode;
}
I couldn't get authorized because django-rest-auth wasn't properly configured for token authorization. The solution was to add TokenAuthentication to the default authentication classes in django settings.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
)}

Resources