How to architect DAL for WebService exposure? - web-services

We have a highly specialized DAL which sits over our DB. Our apps need to use this DAL to correctly operate against this DB.
The generated DAL (which sits on some custom base classes) has various 'Rec' classes (Table1Rec, Table2Rec) each of which represents the record structure of a given table.
Here is a sample Pseudo-class...
Public Class SomeTableRec
Private mField1 As String
Private mField1isNull As Boolean
Private mField2 As Integer
Private mField2isNull As Boolean
Public Sub New()
mField1isNull = True
mField2isNull = True
End Sub
Public Property Field1() As String
Get
Return mField1
End Get
Set(ByVal value As String)
mField1 = value
mField1isNull = False
End Set
End Property
Public ReadOnly Property Field1isNull() As Boolean
Get
Return mField1isNull
End Get
End Property
Public Property Field2() As Integer
Get
Return mField2
End Get
Set(ByVal value As Integer)
mField2 = value
mField2isNull = False
End Set
End Property
Public ReadOnly Property Field2isNull() As Boolean
Get
Return mField2isNull
End Get
End Property
End Class
Each class has properties for each of the fields...
Thus I can write...
Dim Rec as New Table1Rec
Table1Rec.Field1 = "SomeString"
Table2Rec.Field2 = 500
Where a field can accept a NULL value, there is an additional property which indicates if the value is currently null.
Thus....
Dim Rec as New Table1Rec
Table1Rec.Field1 = "SomeString"
If Table1Rec.Field1Null then
' This clearly is not true
End If
If Table1Rec.Field2Null then
' This will be true
End If
This works because the constructor of the class sets all NULLproperties to True and the setting of any FieldProperty will cause the equivalent NullProperty to be set to false.
I have recently had the need to expose my DAL over the web through a web service (which I of course intend to secure) and have discovered that while the structure of the 'Rec' class remains intact over the web... All logic is lost..
If someone were to run the previous piece of code remotely they would notice that neither condition would prove true as there is no client side code which sets null to true.
I get the feeling I have architected this all wrong, but cannot see how I should improve it.
What is the correct way to architect this?

Not sure if I fully understand the question, but you can have nullable data types in XML.
So this...
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class Testing
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function GetObjects() As Generic.List(Of TestObject)
Dim list As New Generic.List(Of TestObject)
list.Add(New TestObject(Nothing, "Empty ID Object"))
list.Add(New TestObject(1, "Full ID Object"))
list.Add(New TestObject(2, Nothing))
Return list
End Function
Public Class TestObject
Public Sub New()
_name = String.Empty
_id = Nothing
End Sub
Public Sub New(ByVal id As Nullable(Of Integer), ByVal name As String)
_name = name
_id = id
End Sub
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _id As Nullable(Of Integer)
Public Property ID() As Nullable(Of Integer)
Get
Return _id
End Get
Set(ByVal value As Nullable(Of Integer))
_id = value
End Set
End Property
End Class
End Class
outputs this (with nullable areas)
<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfTestObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<TestObject>
<Name>Empty ID Object</Name>
<ID xsi:nil="true" />
</TestObject>
<TestObject>
<Name>Full ID Object</Name>
<ID>1</ID>
</TestObject>
<TestObject>
<ID>2</ID>
</TestObject>
</ArrayOfTestObject>

Web services are designed to expose operation(methods) & data contracts but not internal implementation logic. This is a "good thing" in the world of service-oriented architecture. The scenario you describe is a remote/distributed object architecture. Web services will not support what you are trying to do. Please see this post for more information.

Related

How to create a list of values inside application.properties file and how to retrieve that list inside controller class using springboot

My requirement is to create a list of values inside application.properties file.
com.mail = aaaa, bbbb, cccc
I want to retrieve these values in my controller class and iterator over each value and should check with the requestbody/queryparam values which gets, when hitting an API
Consider I have an API
#RestController
#RequestMapping("/response")
public class HomeController {
#PostMapping("/postbody")
public String postBody(#RequestBody String fullName) {
//here I have to validate the fullName with the list I created in the application.properties
Eg: if(fullname.equals(aaaa) or if(fullname.equals(bbbb) or if(fullname.equals(cccc)
// I want to iterator over the list to check any value is matching with fullName.
}}
How to declare list of values inside application.properties? How to retrieve that list inside controller class? Post retrieving how to iterate over the list to check whether it matches with requestbody/queryparam value?
Please provide me with solution. Thank you
Split the list using a comma as the delimiter.
private String[] mailList;
public HomeController( #Value("${com.mail}") final String mail) {
mailList = mail.split(",")
}
You can now use mailList inside postBody method.
use comma separated values in application.properties
com.mail = aaaa, bbbb, cccc
Java code for access
#Value("${com.email}")
String[] mailList;
It worked.
In Application. properties you will add the parameter with values separated with ','
com.mail = aaaa,bbbb,cccc
in the controller will get the Values
#Value("${com.mail}")
private List<String> mailListValues;
#RestController
#RequestMapping("/response")
public class HomeController {
#Value("${com.mail}")
private List<Object> mailListValues;
#PostMapping("/postbody")
public String postBody(#RequestBody String fullName) {
if(!mailListValues.isEmpty()){
long countOfMatch = mailListValues.stream()
.filter(item->item.equals(fullName)).count();
if(countOfMatch >0)
// your Business .....
}
}}
please check images

LiteDB - find data object via List.contains

A simplified version. I have two classes:
Public Class mSystem
Public Property ID as ObjectID
Public Property Name as string
End Class
Public Class mEmulator
Public Property ID as ObjectID
Public Property Name as string
<BsonRef("mSystems")>
Public Property AssociatedSystems as New List(Of mSystem)
End Class
Public Class Main
Public Sub EmaultorsLinkedToSystem
dim SelectedSystem as mSystem = db.Collections.mSystems.Find(Function(x) x.Name = "Sony Playstation").FirstOrDefault
test = db.Collections.mEmulators.Include(Function(x) x.AssociatedSystems).Find(Function(y) y.AssociatedSystems.Contains(SelectedSystem)).ToList
End sub
End Class
Now I know one mEmulator data object has "Sony Playstation" in its List(of mSystem). However, test returns null. Why isn't this finding it? I've tried a few permutations, but cant get this to work. Any ideas?
The Include method is used for resolving references to other collections, and you're not using BsonRef with AssociatedSystems (at least not in this example you provided). In your example, the instances of mSystem in AssociatedSystems are not being stored in a separate collection, but as an array of embedded documents in the emulators collection.
Try removing the Include call, it should work fine.

how to define and access array in grails from config.groovy file

I have a harcoded value in one of my controller
public regions = ['code1','code2']
Now have to read these values from config.groovy file,
I tried to define in config.groovy:-
region = "code1,code2"
in mycontroller :-
def aws = grailsApplication.config.awsRegions;
public awsRegions = aws.split(",")
But it didn't work.
In the Config.groovy you can do:
awsRegions = ['Region 1', 'Region 2']
Then in your Controller you can do:
def awsRegions = grailsApplication.config.awsRegions
Your changes are not working in the comments with Sathish Kumar because you are calling your property "awsRegion" in Config.groovy and accessing it with "grailsApplicatio.config.awsRegions". The keys must match.
1
public regions = ['code1','code2']
should that not be
public List regions = ['code1','code2']
or
public List<String> regions = ['code1','code2']
In the world of groovy / grails public is not required so long as it is not a static variable
2
def aws = grailsApplication.config.awsRegions;
public awsRegions = aws.split(",")
When in doubt :
def aws = grailsApplication.config.awsRegions;
println "aws is ${aws} object class is ${aws.getClass()}"
You should find the println returns [element,e2,e3] within a List already. The getClass() of something tells you what it actually is so you should find it is already a list and does not require the additional split which you would do on a flat string

VB.net how can I split this?

I am trying to split this code in VB.net (owner_id) this is the data string.
yt.setConfig('DISTILLER_CONFIG', {"signin_url": "https:\/\/accounts.google.com\/ServiceLogin?hl=da\u0026continue=http%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26app%3Ddesktop%26feature%3Dcomments%26hl%3Dda%26next%3D%252Fall_comments%253Fv%253DZNW_uQaYfB0\u0026uilel=3\u0026passive=true\u0026service=youtube", "host_override": "https:\/\/plus.googleapis.com", "query": "http:\/\/www.youtube.com\/watch?v=ZNW_uQaYfB0", "channel_id": "UCe4LM_eKc9ywRmVuBm5pjQg", "first_time_comment_promo": false, "privacy_setting": "PUBLIC", "visible": true, "pinned_activity": null, "page_size": 100, "owner_id": "e4LM_eKc9ywRmVuBm5pjQg", "reauth": false, "video_id": "ZNW_uQaYfB0"});
So far I have tried this code, but it doesn't work. Already declared the owner_id string..
owner_id = (Split(data, """owner_id"": """)(1).Split("""")(0)
But it does not work.
EDIT:
How can I select the JSON into a string that I want to split from these scripts..?
http://pastebin.com/50bxc83T
This is JSON, string splitting it is not a great idea, but rather you should de-serialize the JSON into a class object using Json.NET, like this:
Public Class DistillerConfigResults
Public Property DISTILLER_CONFIG As DistillerConfig
End Class
Public Class DistillerConfig
Public Property signin_url As String
Public Property host_override As String
Public Property query As String
Public Property signin_url As String
Public Property channel_id As String
Public Property first_time_comment_promo As Boolean
Public Property privacy_setting As String
Public Property visible As Boolean
Public Property pinned_activity As Object
Public Property page_size As Integer
Public Property owner_id As String
Public Property reauth As Boolean
Public Property video_id As String
End Class
Now you can actually deserialize the JSON into your class object, like this:
Dim a As DistillerConfigResults = JsonConvert.DeserializeObject(Of DistillerConfigResults)(jsonString)
I would suggest using Regex:
"owner_id": "([\d\w]*)"
but only if you really want to parse this single key/value pair. If more should be extracted I would rather think about extracting JSON and deserializing it in normal way.
Working example:
Dim regex As Regex = New Regex("""owner_id"": ""([\d\w]*)""")
Dim match As Match = regex.Match("...here your string...")
If match.Success Then
Console.WriteLine(match.Groups(1).Value)
End If
if there are multiple parts like yt.Config(...) you can include the desired one identifier into regular expression, for example:
Dim regex As Regex = New Regex("yt.setConfig\('DISTILLER_CONFIG'.*""owner_id"": ""([\d\w]*)""")

assert property of mocked object has been assigned correctly using Rhino.Mocks

In a (web) application I've implemented the MVP pattern for seperation of core concerns. My presenters directly query the database using LINQ-to-NHibernate, or sometimes they use query objects when the query becomes complex (but I digress).
An simple example of one of my presenters is as follows (note: VB.NET is not my preference, but a requirement for this):
Public Class CampusListPresenter
Inherits BasePresenter(Of ICampusListView)
Public Sub New(ByVal view As ICampusListView)
MyBase.New(view)
End Sub
Public Sub NeedDataSource()
Using uow As ISession = _sessionManager.OpenSession()
_view.DataSource = uow.Queryable(Of Campus)() _
.Cacheable() _
.AsEnumerable()
End Using
End Sub
End Class
The (simplified) base presenter class is as follows:
Public MustInherit Class BasePresenter(Of TView)
Protected _view As TView
Protected _sessionManager As ISessionManager
Public Sub New(ByVal view As TView)
Guard.Against(view Is Nothing, "view cannot be null.")
_view = view
End Sub
Public WriteOnly Property SessionManager As ISessionManager
Set(ByVal value As ISessionManager)
_sessionManager = value
End Set
End Property
End Class
I'm trying to unit test my presenters (specifically the LINQ queries) using NUnit and Rhino Mocks. In my unit test case for the above CampusListPresenter, I pass a mocked view to the presenter. Essentially I want perform an assertion on this mocked view object to confirm the Datasouce property gets set appropriately. However, this is always null.
A (simplified) example of my unit test is as follows (understand I'm relatively new to proper unit testing):
<TestFixture()> _
Public Class CampusListPresenterTests
Dim _realSessionManager As ISessionManager
<TestFixtureSetUp()> _
Public Sub TestFixtureSetUp()
_realSessionManager = DefaultSessionManager.Instance
End Sub
Dim _view As ICampusListView
Dim _fakeSessionManager As ISessionManager
<SetUp()> _
Public Sub Setup()
_view = MockRepository.GenerateMock(Of ICampusListView)()
_fakeSessionManager = MockRepository.GenerateMock(Of ISessionManager)()
End Sub
<Test()> _
Public Sub NeedDataSource_UsingRealSession_DataSourceIsAssigned()
'Arrange
Dim realSession As ISession = _realSessionManager.OpenSession()
_fakeSessionManager.Expect(Function(sm) sm.OpenSession()).Return(realSession)
'Act
Dim presenter As New CampusListPresenter(_view)
presenter.SessionManager = _fakeSessionManager
presenter.NeedDataSource()
'Assert
_fakeSessionManager.VerifyAllExpectations()
Assert.AreEqual(_view.DataSource, realSession.Queryable(Of Campus)())
End Sub
End Class
I actually setup my unit tests to use an in memory SQLite database and populate/destroy data in the setup/teardown methods, but this has all been omitted from the above example for simplicty.
Basically, in this unit test I'm returning a real NHibernate ISession from a mocked session manager (a class used for session management - think Castle.Facilities.NHibernateIntegration) so that the LINQ-to-NHibernate can/will actually return valid enumerable results. Anyway in the presenter implementation I assign the views datasource (inside NeedDataSource), but when I do an assertion on this property the assigned value is always null.
Can anyone help me out?
Kind regards,
Ryan.
The mocked ICampusListView is unable to keep hold of the assigned datasource object. Here are two possible ways to fix this. First, you could use a stub instead of a mock (for more background info on the difference between mocks and stubs, see this post):
_view = MockRepository.GenerateStub(Of ICampusListView)()
If you do want to use mocks instead of stubs, use Expect and VerifyAllExpectations on the ICampusListView object in your test:
'Arrange
Dim realSession As ISession = _realSessionManager.OpenSession()
_fakeSessionManager.Expect(Function(sm) sm.OpenSession()).Return(realSession)
_view.Expect(Function(v) v.SetDataSource(Arg(Of DataSource).Is.Anything))
'Act
Dim presenter As New CampusListPresenter(_view)
presenter.SessionManager = _fakeSessionManager
presenter.NeedDataSource()
'Assert
_fakeSessionManager.VerifyAllExpectations()
_view.VerifyAllExpectations()
Assert.AreEqual(_view.DataSource, realSession.Queryable(Of Campus)())