where to Storing a managed object in custom app hosted in cumulocity - cumulocity

Where to store the managed object for the custom angular 6 App which is hosted inside the cumulocity
Thanks
BA

If you need to store metadata for your applications the inventory is the right place.
A good approach is to give your object either a unique type for some unique flag.
{
"type": "myUniqueType",
"myUniqueFlag": {}
}
That way you can easily query it again with either type=myUniqueType or fragmentType=myUniqueFlag

Related

Multi-tenant ASP.Net MVC application - Where to store tenant specific data

I'm working on a requirement to change an existing ASP.NET MVC application to become multi-tenant ready. The application was built for "only one customer" by other means, for each client there's a new installation of the MVC app. The application has its database structure prepared to have "multi" websites inside one MVC app, so all the database queries already take the "site" into consideration (siteId).
I have several questions regarding multi-tenancy applications and I'm still studying it. Today I started doing changes on the MVC app and I came across on one thing. The application has a table with several configurations. Things like AppSMTPServer, AppShowLoginBox and etc. These are parameters created to make the app dynamic.
All these configurations are currently stored in the ApplicationState inside a static class, something like this:
public static IDictionary<String, String> Configurations
{
get
{
if (HttpContext.Current.Application[CONFIGURATIONS] == null)
{
LoadConfiguration();
}
return (IDictionary<String, String>)HttpContext.Current.Application[CONFIGURATIONS];
}
private set
{
HttpContext.Current.Application[CONFIGURATIONS] = value;
}
}
My question is. If I change the MVC to become multi-tenant ready, each tenant will have its own configuration values. So, I cannot store them in the ApplicationState anymore as it will be populated on application_start and will stay there for good.
What are the options for storing tenant specific configuration data? I looked on several sites and couldn't find a "good practices" on this. If I missed something that would help, please leave a comment. Thanks!
In my experience in building multi-tenant app's this use-case can be handled as follows,
Data remains in the Db
Upon a tenant login, we might require their config values, we can fetch from the db store and add them to a cache [redis - distributed cache]
similarly for each tenant hit, we can cache them, this way as the application is being repeatedly used, the more static data goes in to the cache and lesser the load on the app and the cache and higher the response times

What is an efficient way to create/manage RESTful API with grails?

I've built my first grails application. My URL mappings are what the default application provides:
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
Senario
I have a controller called ColorController with actions save and list. It simply does something like this:
def save () {
def colorInstance = new Color(params)
colorInstance.save(flush: true)
}
def list () {
[colorList: Color.list, colorTotal: Color.count()]
}
I would like to build a simple API for these actions.
The save action should accept parameters as JSON and provide a successful message if the records save.
The list action should provide the list as JSON
Questions
Should I make a separate URL mapping for api? (e.g. http://<domain>/<app>/rest/controller/action)
Should I be making a separate controller for my API's
I am using spring security plugin for authentication. But at some point I might want to authenticate the restful api as well. What are some solutions for that?
If I use the same controller, how can I modify these simple actions to do what I need.
Before even looking below for my opinion/answers I would suggest to visit this SO Question for the basic understanding of RESTful WS in Grails.
Opinions:
"The save action should accept parameters as JSON and provide a successful message if the records save" - Save is mapped to POST RESTful. Instead of binding a JSON body to params it is bound to the request. In order to access the JSON object you just need to use request.JSON in the action method.
request.JSON instanceof JSONObject
"The list action should provide the list as JSON" - list() action is mapped to a GET Request and you can render the map as JSON in the list() as below
//Controller list()
import grails.converter.JSON
def list () {
[colorList: Color.list, colorTotal: Color.count()] as JSON
}
Answers to Questions:-
Should I make a separate URL mapping for api?
Abiding by the basics of REST, the client should only access the resource (Color in this case) and should not bother about the underlying controller or action. The server side logic should be abstracted from the client. URL Mapping is what the client would use to as form of request. I would have something like this in my url mapping for Color Resource.
/color/$id?(resource: "color")
or
/color/$id?(controller: 'color'){
action = [GET: "list", POST: "save"]
}
Should I be making a separate controller for my API's? - Depends on the way the App is designed. You also can have the above controller as the API. For example, currently I am working on a grails app which used AngularJS in the front End which connects to the Grails APP RESTFully. In order to achieve I had a RestClientController which works as an API to Angular. The rationale behind having a REST api in the same app is that in future we can expose the underlying service to external clients other than the Angular client present in the app itself.
I am using spring security plugin for authentication. But at some point I might want to authenticate the restful api as well. What are some solutions for that? - You can use Spring Security here as well. In my case I am using the plugin and I secure the controller by using the plugin's annotated component #Secured. I have custom OAuth enabled as well for authorization which interacts to the company wide LDAP and AD Groups.
If I use the same controller, how can I modify these simple actions to do what I need. - I think you would have got the answer to this question by now (after going through the SO question I mentioned above). Here is my opinion, controller actions can route to appropriate service classes which does the business implementations based on the request parameters.
For example,
//Action
def show(){
if(params.id){
colorService.getColor()
} else {
colorService.searchColor()
}
}
In the above example, the url mapping would be /color/123 or /color. In the former case, it will get the color and in the later it will search the colors

WCF Data Service Change Tracking: How to cancel save changes and revert to original values for an object

I have a WCF Data Service that is wrapping an Entity Framework 4 data model. I am connecting a WPF client to the service using the WCF Data Services Client library.
Is it possible in WCF Data Services to undo / cancel changes to tracked objects ?
scenario : In the UI I allow a user to edit an object. I have save and cancel buttons. If the user chooses to save I call SaveChanges() on my WCF context and changes are sent to the database via the WCF service. If the user clicks cancel I want to undo the changes and revert to the original property values of the current object.
I know that the WCF data services client library has change tracking built in - but I cannot find any way at accessing this information.
In Entity Framework the context supports the Refresh method and you can specify RefreshMode.StoreWins and pass in the object - this will effectively cancel / undo any changes.
documented here : http://msdn.microsoft.com/en-us/library/bb896255.aspx
Any suggestions on how I can achieve the same thing in WCF DataServices in my client application ?
cheers
Chris
The only "solution" I know of is:
var oldMergeOption = _service.MergeOption;
_service.MergeOption = MergeOption.OverwriteChanges;
try {
_service.YourQueryable.Where(x => x.Id==oldObject.Id).Single();
} finally {
_service.MergeOption = oldMergeOption;
}
This should replace the values of "oldObject" with the values stored in the DB. However, I'm not sure if the object returned by Single() will always be the same as "oldObject".
I typically refrain from operating on entities within the DataServiceContext until I'm ready to commit those changes to the database. I don't treat my entities as part of my domain model so I create a specific domain model that adapts my model objects to entity objects using adapters and a repository class. This way, all operations within by domain model are self-contained until I'm ready to commit them to the database. A fantastic article from Ben Day on what I'm referring to can be found here: http://visualstudiomagazine.com/articles/2011/04/01/pfcov_silverlight-mvvm-tips.aspx

How to setup JsonWritter for ext.net store

I cannot find the solution for configuring ext.net restful store. Reading and deleting records works good, but I need also update and create functionality. For this I need to send data to WCF (restful) service in Json or XML format. In classic ExtJS I would create a store with JsonWritter, but how to do that in ext.net ? Store doesn't have public property Writter (or similar), so I cannot use ... markup. I also didn't find a way how to set writter later (on the place like Ext.onReady...).
Of course, I can gather all data and call WCF service directly (ajax) and then just refresh the store.
But that is not that nice like it would be when store handles all CRUD operation by itself.
Thanks for any help
Please investigate the following sample
http://examples.ext.net/#/GridPanel/Restful/Overview/

Best way to share data between .NET application instance?

I have create WCF Service (host on Windows Service) on load balance server. Each of this service instance maintain list of current user. E.g. Instance A has user A001, A002, A005, instance B has user A003, A004, A008 and so on.
On each service has interface that use to get user list, I expect this method to return all user in all service instance. E.g. get user list from instance A or instance B will return A001, A002, A003, A004, A005 and A008.
Currently I think that I will store the list of current users on database but this list seem to update so often.
I want to know, is it has another way to share data between WCF service that suit my situation?
Personally, the database option sounds like overkill to me just based on the notion of storing current users. If you are actually storing more than that, then using a database may make sense. But assuming you simply want a list of current users from both instances of your WCF service, I would use an in-memory solution, something like a static generic dictionary. As long as the services can be uniquely identified, I'd use the unique service ID as the key into the dictionary and just pair each key with a generic list of user names (or some appropriate user data structure) for that service. Something like:
private static Dictionary<Guid, List<string>> _currentUsers;
Since this dictionary would be shared between two WCF services, you'll need to synchronize access to it. Here's an example.
public class MyWCFService : IMyWCFService
{
private static Dictionary<Guid, List<string>> _currentUsers =
new Dictionary<Guid, List<string>>();
private void AddUser(Guid serviceID, string userName)
{
// Synchronize access to the collection via the SyncRoot property.
lock (((ICollection)_currentUsers).SyncRoot)
{
// Check if the service's ID has already been added.
if (!_currentUsers.ContainsKey(serviceID))
{
_currentUsers[serviceID] = new List<string>();
}
// Make sure to only store the user name once for each service.
if (!_currentUsers[serviceID].Contains(userName))
{
_currentUsers[serviceID].Add(userName);
}
}
}
private void RemoveUser(Guid serviceID, string userName)
{
// Synchronize access to the collection via the SyncRoot property.
lock (((ICollection)_currentUsers).SyncRoot)
{
// Check if the service's ID has already been added.
if (_currentUsers.ContainsKey(serviceID))
{
// See if the user name exists.
if (_currentUsers[serviceID].Contains(userName))
{
_currentUsers[serviceID].Remove(userName);
}
}
}
}
}
Given that you don't want users listed twice for a specific service, it would probably make sense to replace the List<string> with HashSet<string>.
A database would seem to offer a persistent store which may be useful or important for your application. In addition it supports transactions etc which may be useful to you. Lots of updates could be a performance problem, but it depends on the exact numbers, what the query patterns are, database engine used, locality etc.
An alternative to this option might be some sort of in-memory caching server like memcached. Whilst this can be shared and accessed in a similar (sort of) way to a database server there are some caveats. Firstly, these platforms are generally not backed by some sort of permanent storage. What happens when the memcached server dies? Second they may not be ACID-compliant enough for your use. What happens under load in terms of additions and updates?
I like the in memory way. Actually I am designing a same mechanism for one my projects I'm working now. This is good for scenarios where you don't have opportunities to access database or some people are really reluctant to create a table to store simple info like a list of users against a machine name.
Only update I'd do there is a node will only return the list of its available users to its peer and peer will combine that with its existing list. Then return its existing list to the peer who called. Thats how all the peers would be in sync with same list.
The DB option sounds good. If there are no performance issues it is a simple design that should work. If you can afford to be semi realtime and non persistent one way would be to maintain the list in memory in each service and then each service updates the other when a new user joins. This can be done as some kind of broadcast via a centralised service or using msmq etc.
If you reconsider and host using IIS you will find that with a single line in a config file you can make the ASP Global, Application and Session objects available. This trick is also very handy because it means you can share session state between an ASP application and a WCF service.