We have the adhoc cache enabled, but we are using a custom query executer to retrieve the data. For jasperserver it looks like it's using one datasource while instead it could be a different one then before.
We have a multitenancy setup for jasperserver (4.7)0.
In this we have a couple of adhoc views wich are the same for every tenant and user. We have a custom query executer wich makes sure the report is run on the right database etc.
But when we turn on the adhoc cache, it will cache results for a certain adhoc view. To prevent other users from seeing the wrong data (from the cache) we would like to add the tenantId and the UserId to the adhoc cache key, or maybe insert that parameter from within the custom query executer.
Does anybody know if this is possible ?
Greetings,
Peter
One way of doing is, is to create your own version of the DefaultCacheKeyInterceptor, and add a User object (even if there is none specified in the report).
Then edit the applicationContext-datarator.xml, and change the class entry of the keyInterceptor bean definition to your own class.
Related
I'm currently developing an application in the SAP BTP for multiple users. In the application you have one table where all responsibilities of a specific task are written down. These responsibilities may overlap between the users, which means that for one responsibility multiple users are mentioned.
In the application the users should click on either accept or reject if they still are responsible for this task. After they have given their feedback, they can click on a save button to write everything via a batch submit to the hana db. If they are not responsible anymore their name should be removed from the tasks and they should not see this task anymore.
The problem I am facing is that currently everything is stored in one database table and if one user gives feedback to some entries while another user works on the same entries, the user who saves his entries last will override the first one.
I have tried searching for a delta insert into the database or to live update after each user input or to lock the data when another user is currently working. But none of these seem to work fine, because users would still be able to override each others entries or they may lock some entries forever.
My question therefore is, what is the usual approach to manage multiple user inputs on a single table or is using a single table a bad practise at first?
My second question would be if sapui5 supports this approach or if I can handle this in another way?
You need to do server-side validation, before the save action.
UI5 does not support this directly, you can handle it by yourself.
Because we are stateless with ui5 / data you could use the draft concept
https://experience.sap.com/fiori-design-web/draft-handling/
Or something like already said backend logic with checks before safe.
I have a scheduled instance emailing to a user. The instance works fine and user gets email. But the data in the report attached to the email is stale. It is missing item codes that do show up in the report if you go view it directly in web browser at BO server.
If I create a new instance scheduled to send to me - data looks up to date and good to go. If I add myself on the instance sending stale report and re-run the instance, I also get the stale version.
I'm worried about how whatever this is could be impacting other reports/users in the company without our knowledge. And also want to fix this one instance.
Is there some caching or other options that could be causing this? Why is the instance sending stale data?
Thanks!!
I figured this out. Turns out someone added record select formulas to the base report but did not re-create the scheduled instance. I looked at meta data from CI_INFOOBJECTS etc to see the record select formula on the instance. It does not match the updated record select on the base report.
This highlights a great best practice to keep in mind in this environment. KEEP YOUR FILTERS OUT OF CRYSTAL REPORTS! Keep your record selection and data transform logic inside SQL server in stored procs or views. That way you can update your report filter criterias without have to re create every scheduled report instance after every little report change :)
I'll make it quick. I'm building an application that will relay heavily on Firebase, and especially the Real Time Database. It functions purely off of user input, which can obviously change and mutate. Essentially they will be sending what I'm calling Bundles to the database. They contain vital information about location, information, etc. So, the question, how can I structure the add script from my application so I can make sure that no duplicate data bundle names are generated, as it wouldn't be ideal at all. Using a users UID also wouldn't be ideal as that could lead to an immediate duplicate data if they send two Bundles. Thanks everybody!
You'll have to use childByAutoId when creating the "bundle" node, This will create a node with a unique identifier.
Source: https://firebase.google.com/docs/database/ios/save-data
I accomplished this by using the push function in the firebase documentation. This allows me to not only add the data bundle right into a list of other data bundles, but it also includes the server providing it with a unique key, thus removing all chances of duplicate bundle names occurring. You can check out the same docs by clicking here
I seem to have trouble understanding a concept with Azure Mobile Services that are using .NET backend with Code First and migrations enabled.
Currently I have deployed a "productive" instance of AMS, let's say it's called "AMD". It is running at amd.azure-mobile.net. Database structure has been created using Enable-Migrations and Add-Migration. This is all fine now for this productive instance, it is running and is fully functional.
Now I want to create an INT instance to have a separate environment for tests etc. I want to name it differently, say "AMDINT". It should run at amdint.azure-mobile.net and should also have a separate database, to make it impossible to break stuff in production.
Originally I thought I could pull it off like this:
1) Create the new instance under amdint.azure-mobile.net with a new database to go with it
2) Create a web.config transform for a newly created configuration called "INT" (primarily to change the MS_MobileServiceName value to the new name)
3) Download the publishing profile of the new instance, import it, make it use the "INT" configuration and deploy it
The new bits apparently get deployed, but whenever I hit an endpoint that requires DB access, an error will be generated in the logs and it says
Database initialization failed. Could not initialize one or more objects in schema 'amdint'. Please ensure that the database connection string is correct. For more details on the error, please see the inner exception. ---> System.InvalidOperationException: Database initialization failed. Could not initialize one or more objects in schema 'amdint'. Please ensure that the database connection string is correct. For more details on the error, please see the inner exception. ---> System.Data.SqlClient.SqlException: User does not have permission to perform this action.
So I used Azure User Management Console (AUMC) to see if permissions were missing for the user that is being specified in the connection string in the configuration tab of the new service, but the user was present for that database. I also edited the user's permissions to include every possible right, but this did not change anything.
Then I noticed that the migrations files specify a database schema for the Up() and Down() methods. For a test, I changed these strings from "amd.tablename" to "amdint.tablename" and was pretty confident I had nailed it.
However, this still brought the same error. So I used the database user's credentials from the connection string and opened database editor from the management console in the browser, and saw that with all the added rights it can edit the database schema just fine (created and deleted a table for testing purposes). However, no single table has been created by the Initializer; the database was blank.
But since I was able to edit, I somehow believe that either the error message about insufficient permissions is misleading or that I am looking at the wrong place.
Does anyone know of a way to accomplish what I am trying to do? I don't want to have separate Visual Studio projects for production and INT, obviously.
I think what you're running into is the issue that Mobile Services creates a special schema user that has rights to only tables in that schema. This schema has the same name as your mobile service. So, even if the two databases are on the same DB server, the connection string for a DEV mobile service wouldn't work for PROD, and vice versa.
Here are some suggestions to make your setup easier:
In the Azure Portal, Mobile Services doesn't allow modifying the connection string that it creates for you, which is called MS_TableConnectionString. I recommend that in your case, you create a new connection string with a different key and use that for each of your services, e.g., AMD_TableConnectionString. Make sure that for each service, the database user has access to each schema (more on that in a minute).
To use the new connection string, change your super constructor call in your DbContext class, e.g., base("name=AMD_TableConnectionString").
Use the application setting MS_MobileServiceName in your web.config and/or the Azure Portal to set the schema for your service. This is use by the Mobile Service Entity Framework initializer.
NOTE: If you're already using separate databases for DEV and PROD, you have the option of using the same schema name for both your DEV and PROD instances, which might make testing and setup easier.
Either way, the database user in the connection string must have full permissions to whatever schema name you specify in MS_MobileServiceName.
(You probably have this part working.) Make sure that the Mobile Services SQL Generator is run. It will automatically run if you set an Entity Framework database initializer, but some folks like to have all database changes done through DB migrations. In that case, follow this tutorial here: https://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-how-to-use-code-first-migrations/#using-code-first-migrations-without-an-initializer
I tried searching a while and I did not find a proper convincing answer. Hence the question. I know plist and mysql are kind of on two opposite ends, but I have a solution approach using plist which can be simple. But I doubt the solution approach and feel it is not an elegant solution.
Model:
User has profile with various information such as name, email, date of birth etc. He also has a set or list of other information such as books, hobbies etc. So essentially from a plist perspective it will be nested arrays.
<name>
<email>
<date of birth>
<books>
<book1>
<book2>
<Hobbies>
<hobby1>
<hobby2>
...
From a mysql db perspective, there will be 3 tables. One for profile, one for books and one for hobbies. One row per profile with foreign key to Books and Hobbies table.
Problem:
I need to store this information on the server and retrieve on iphone on request
Remember, this user will be able to view the profile of various other users based upon some filter criteria. So all I am asking is where and how to store the profile information of all the users, and such that this user can view them on his iphone when he wants to.
Solution approaches:
Approach 1: (using plist)
For every user, store a plist file on the server. To get the information on iphone, create a http request to get the plist, then display info on iphone from plist using standard methods.
So if the server is at xyz.com, I can get the plist at path xyz.com/userid/profile.plist
Approach 2: (using mysql)
Store the data in mysql database. Send http request to access a php file. The php code queries the profile table by userid, and then queries the Books and Hobbies table by the foreign keys. Create an array of the result. And send the resultant array back to iphone. iPhone now displays profile info from that array.
Which approach is better for a best practices, performance and scalability perspective?
There would be eventually 1000s of profiles. In the first approach that means there will 1000 different plist files on server. In second approach it means 1000 rows in profile table.
Approach 3: (using [insert server side database name] and CoreData or SQLite)
Create you tables in [insert server side database name] and then create the necessary table structures/entity model for your device. When a user does not have any data on the device make an http request, insert into to your local store on the device, and read from the device from then on or until an update is required.
Not Approach 1, if for no other reason than the fact that anyone can replace "userid" with someone else's user id and get xyz.com/userid/profile.plist