Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
V
vospace-rest
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Redmine
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
VOSpace INAF
vospace-rest
Commits
623b48b9
Commit
623b48b9
authored
4 years ago
by
Sara Bertocco
Browse files
Options
Downloads
Patches
Plain Diff
setNode added
parent
c3e356d6
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/main/java/it/inaf/oats/vospace/SetNodeController.java
+18
-8
18 additions, 8 deletions
src/main/java/it/inaf/oats/vospace/SetNodeController.java
src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java
+209
-13
209 additions, 13 deletions
src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java
with
227 additions
and
21 deletions
src/main/java/it/inaf/oats/vospace/SetNodeController.java
+
18
−
8
View file @
623b48b9
...
...
@@ -10,9 +10,12 @@ import it.inaf.oats.vospace.persistence.NodeDAO;
import
java.util.List
;
import
javax.servlet.http.HttpServletRequest
;
import
net.ivoa.xml.vospace.v2.Node
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RestController
;
...
...
@@ -20,6 +23,8 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
public
class
SetNodeController
extends
BaseNodeController
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
SetNodeController
.
class
);
@Autowired
private
NodeDAO
nodeDao
;
...
...
@@ -29,9 +34,10 @@ public class SetNodeController extends BaseNodeController {
@PostMapping
(
value
=
{
"/nodes"
,
"/nodes/**"
},
consumes
=
{
MediaType
.
APPLICATION_XML_VALUE
,
MediaType
.
TEXT_XML_VALUE
,
MediaType
.
APPLICATION_JSON_VALUE
},
produces
=
{
MediaType
.
APPLICATION_XML_VALUE
,
MediaType
.
TEXT_XML_VALUE
,
MediaType
.
APPLICATION_JSON_VALUE
})
public
Node
setNode
(
@RequestBody
Node
node
,
User
principal
,
HttpServletRequest
request
)
{
public
ResponseEntity
<
Node
>
setNode
(
@RequestBody
Node
node
,
User
principal
,
HttpServletRequest
request
)
{
String
path
=
getPath
();
LOG
.
debug
(
"setNode called for path {}"
,
path
);
//The service SHALL throw a HTTP 404 status code including a NodeNotFound
//fault in the entity-body if the target Node does not exist
...
...
@@ -48,10 +54,15 @@ public class SetNodeController extends BaseNodeController {
// The service SHALL throw a HTTP 403 status code including a PermissionDenied fault
// in the entity-body if the request attempts to modify a read-only Property.
// This method cannot be used to modify the Node type.
String
storedNodeType
=
toBeModifiedNode
.
getType
();
String
newNodeType
=
node
.
getType
();
if
(!
storedNodeType
.
equals
(
newNodeType
))
{
LOG
.
debug
(
"setNode trying to modify type. Stored "
,
storedNodeType
+
", requested "
+
newNodeType
);
throw
new
PermissionDeniedException
(
path
);
}
// This method cannot be used to modify the accepts or provides list of Views for the Node.
// This method cannot be used to create children of a container Node.
// For this case, throws exception in NodeDAO
// This method cannot be used to create children of a container Node. (Non capisco, Sara)
// If a parent node in the URI path does not exist then the service SHALL throw a
// HTTP 404 status code including a ContainerNotFound fault in the entity-body
...
...
@@ -79,16 +90,15 @@ public class SetNodeController extends BaseNodeController {
}
//The service SHOULD throw a HTTP 500 status code including an InternalFault fault
// in the entity-body if the operation fails
// Done in NodeDAO
// to be fixed
// A HTTP 200 status code and a Node representation in the entity-body The full
// expanded record for the node SHALL be returned, including any xsi:type
// specific extensions.
return
node
;
return
ResponseEntity
.
ok
(
nodeDao
.
setNode
(
node
))
;
}
...
...
This diff is collapsed.
Click to expand it.
src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java
+
209
−
13
View file @
623b48b9
package
it.inaf.oats.vospace.persistence
;
import
it.inaf.oats.vospace.DeleteNodeController
;
import
it.inaf.oats.vospace.datamodel.NodeProperties
;
import
it.inaf.oats.vospace.datamodel.NodeUtils
;
import
it.inaf.oats.vospace.datamodel.NodeUtils
;
import
it.inaf.oats.vospace.exception.InternalFaultException
;
import
it.inaf.oats.vospace.exception.NodeNotFoundException
;
import
it.inaf.oats.vospace.exception.PermissionDeniedException
;
import
java.sql.Array
;
import
net.ivoa.xml.vospace.v2.Node
;
import
java.sql.PreparedStatement
;
...
...
@@ -22,6 +25,8 @@ import net.ivoa.xml.vospace.v2.DataNode;
import
net.ivoa.xml.vospace.v2.Property
;
import
net.ivoa.xml.vospace.v2.StructuredDataNode
;
import
net.ivoa.xml.vospace.v2.View
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.jdbc.core.JdbcTemplate
;
...
...
@@ -30,6 +35,8 @@ import org.springframework.stereotype.Repository;
@Repository
public
class
NodeDAO
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
DeleteNodeController
.
class
);
@Value
(
"${vospace-authority}"
)
private
String
authority
;
...
...
@@ -46,17 +53,7 @@ public class NodeDAO {
String
path
=
nodeURI
.
replaceAll
(
"vos://[^/]+"
,
""
);
String
parentPath
=
NodeUtils
.
getParentPath
(
path
);
String
sql
=
"SELECT path, relative_path from "
+
"node n join node_vos_path p on n.node_id = p.node_id "
+
"where p.vos_path = ?"
;
List
<
NodePaths
>
paths
=
jdbcTemplate
.
query
(
conn
->
{
PreparedStatement
ps
=
conn
.
prepareStatement
(
sql
);
ps
.
setString
(
1
,
parentPath
);
return
ps
;
},
(
row
,
index
)
->
{
return
getPathsFromResultSet
(
row
);
});
List
<
NodePaths
>
paths
=
getNodePathsFromDB
(
nodeURI
);
if
(
paths
.
isEmpty
())
{
throw
new
IllegalStateException
(
"Unable to find parent node during node creation"
);
...
...
@@ -126,6 +123,101 @@ public class NodeDAO {
return
Optional
.
of
(
node
);
}
public
Node
setNode
(
Node
newNode
)
{
// Verify that the node is in the database
String
nodeURI
=
newNode
.
getUri
();
List
<
NodePaths
>
paths
=
getNodePathsFromDB
(
nodeURI
);
if
(
paths
.
isEmpty
())
{
throw
new
IllegalStateException
(
"Unable to find node during node update"
);
}
if
(
paths
.
size
()
>
1
)
{
throw
new
IllegalStateException
(
"Multiple ltree parent paths during node update"
);
}
// This method cannot be used to modify the accepts or provides list of Views for the Node.
// Only DataNodes has Views (see VOSpace Data Model
// Check if trying to change views getting Views (if present) of the modified node
if
(
newNode
instanceof
DataNode
)
{
DataNode
dataNode
=
(
DataNode
)
newNode
;
List
<
View
>
requestedAcceptedViews
=
dataNode
.
getAccepts
();
List
<
View
>
savedAcceptedViews
=
getAcceptedViewsFromDB
(
paths
.
get
(
0
).
getPath
());
// Get the Views of the saved node
List
<
View
>
requestedProvidedViews
=
dataNode
.
getProvides
();
List
<
View
>
savedProvidedViews
=
getProvidedViewsFromDB
(
paths
.
get
(
0
).
getPath
());
if
(!
requestedAcceptedViews
.
isEmpty
())
{
//se sono non nulle, devo fare i controlli, altrimenti di sicuro l'utente non sta chiedendo di cambiarle
// Check if requestedAcceptedViews are different from the already stored
if
(!
checkIfViewsAreEquals
(
requestedAcceptedViews
,
savedAcceptedViews
))
{
LOG
.
debug
(
"setNode trying to modify accepted Views."
);
throw
new
PermissionDeniedException
(
"Trying to modify accepted views"
);
}
}
if
(!
requestedProvidedViews
.
isEmpty
())
{
//se sono non nulle, devo fare i controlli, altrimenti di sicuro l'utente non sta chiedendo di cambiarle
// Check if requestedAcceptedViews are different from the already stored
if
(!
checkIfViewsAreEquals
(
requestedProvidedViews
,
savedProvidedViews
))
{
LOG
.
debug
(
"setNode trying to modify provided Views."
);
throw
new
PermissionDeniedException
(
"Trying to modify provided views"
);
}
}
}
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"UPDATE node"
);
sb
.
append
(
" SET owner_id = ?, group_read = ?, group_write = ?, is_public = ? "
);
sb
.
append
(
" FROM node_vos_path p WHERE p.vos_path = ? AND p.node_id = node.node_id "
);
jdbcTemplate
.
update
(
conn
->
{
PreparedStatement
ps
=
conn
.
prepareStatement
(
sb
.
toString
());
int
i
=
0
;
ps
.
setString
(++
i
,
NodeProperties
.
getPropertiesStringByURI
(
newNode
,
NodeProperties
.
getPropertyURI
(
"creator"
)));
ps
.
setArray
(++
i
,
fromPropertyToArray
(
ps
,
NodeProperties
.
getPropertiesStringByURI
(
newNode
,
NodeProperties
.
getPropertyURI
(
"groupread"
))));
ps
.
setArray
(++
i
,
fromPropertyToArray
(
ps
,
NodeProperties
.
getPropertiesStringByURI
(
newNode
,
NodeProperties
.
getPropertyURI
(
"groupwrite"
))));
ps
.
setBoolean
(++
i
,
Boolean
.
valueOf
(
NodeProperties
.
getPropertiesStringByURI
(
newNode
,
NodeProperties
.
getPropertyURI
(
"publicread"
))));
ps
.
setString
(++
i
,
paths
.
get
(
0
).
getPath
());
return
ps
;
});
return
newNode
;
}
private
Optional
<
Node
>
getNode
(
String
path
)
{
String
sql
=
"SELECT node_id, type, async_trans, sticky, busy_state, creator_id, group_read, group_write,\n"
+
"is_public, content_length, created_on, last_modified, accept_views, provide_views \n"
+
"FROM node WHERE path = ?"
;
List
<
Node
>
nodes
=
jdbcTemplate
.
query
(
conn
->
{
PreparedStatement
ps
=
conn
.
prepareStatement
(
sql
);
ps
.
setString
(
1
,
path
);
return
ps
;
},
(
row
,
index
)
->
{
return
getNodeFromResultSet
(
row
);
});
if
(
nodes
.
isEmpty
())
{
return
Optional
.
empty
();
}
// Query returns the node (can be container or data)
Node
node
=
nodes
.
get
(
0
);
return
Optional
.
of
(
node
);
}
private
String
getFirstLevelChildrenSelector
(
String
path
)
{
String
select
=
"(SELECT path FROM node WHERE node_id = (SELECT node_id FROM node_vos_path WHERE vos_path = ?))::varchar || '"
;
...
...
@@ -322,10 +414,11 @@ public class NodeDAO {
return
null
;
}
private
List
<
View
>
getViews
(
Array
array
)
throws
SQLException
{
private
List
<
View
>
getViews
(
Array
array
)
{
if
(
array
==
null
)
{
return
null
;
}
try
{
return
Arrays
.
stream
((
String
[])
array
.
getArray
())
.
map
(
uri
->
{
View
view
=
new
View
();
...
...
@@ -333,6 +426,100 @@ public class NodeDAO {
return
view
;
})
.
collect
(
Collectors
.
toList
());
}
catch
(
SQLException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
private
boolean
checkIfViewsAreEquals
(
List
<
View
>
viewsA
,
List
<
View
>
viewsB
)
{
boolean
viewsAreEqual
=
true
;
if
((
viewsA
==
null
||
viewsA
.
isEmpty
())
&&
(
viewsB
==
null
||
viewsB
.
isEmpty
()))
return
true
;
if
((
viewsA
==
null
||
viewsA
.
isEmpty
())
||
(
viewsB
==
null
||
viewsB
.
isEmpty
()))
return
false
;
if
(
viewsA
.
size
()
!=
viewsB
.
size
())
return
false
;
for
(
int
i
=
0
;
i
<
viewsA
.
size
();
i
++)
{
String
viewUriA
=
viewsA
.
get
(
i
).
getUri
();
boolean
found
=
false
;
for
(
int
j
=
0
;
j
<
viewsB
.
size
();
j
++)
{
String
viewUriB
=
viewsB
.
get
(
i
).
getUri
();
if
(
viewUriA
.
compareTo
(
viewUriB
)
==
0
)
{
found
=
true
;
}
}
if
(
found
==
false
)
{
viewsAreEqual
=
false
;
break
;
}
}
return
viewsAreEqual
;
}
private
List
<
View
>
getAcceptedViewsFromDB
(
String
nodePath
)
{
return
getViewsFromDB
(
nodePath
,
"accept_views"
);
}
private
List
<
View
>
getProvidedViewsFromDB
(
String
nodePath
)
{
return
getViewsFromDB
(
nodePath
,
"provide_views"
);
}
private
List
<
View
>
getViewsFromDB
(
String
nodePath
,
String
viewType
)
{
String
sql
=
"SELECT accept_views FROM node WHERE node_id = "
+
"(SELECT node_id FROM node_vos_path WHERE vos_path = ?)"
;
Array
results
=
jdbcTemplate
.
query
(
sql
,
ps
->
{
ps
.
setString
(
1
,
nodePath
);
},
(
rs
)
->
{
if
(
rs
.
next
())
return
rs
.
getArray
(
"accept_views"
);
else
return
null
;
});
return
getViews
(
results
);
}
private
List
<
NodePaths
>
getNodePathsFromDB
(
String
nodeURI
)
{
//String nodeURI = myNode.getUri();
String
path
=
nodeURI
.
replaceAll
(
"vos://[^/]+"
,
""
);
String
parentPath
=
NodeUtils
.
getParentPath
(
path
);
String
sql
=
"SELECT path, relative_path from "
+
"node n join node_vos_path p on n.node_id = p.node_id "
+
"where p.vos_path = ?"
;
List
<
NodePaths
>
paths
=
jdbcTemplate
.
query
(
conn
->
{
PreparedStatement
ps
=
conn
.
prepareStatement
(
sql
);
ps
.
setString
(
1
,
parentPath
);
return
ps
;
},
(
row
,
index
)
->
{
return
getPathsFromResultSet
(
row
);
});
return
paths
;
}
private
class
NodePaths
{
...
...
@@ -350,5 +537,14 @@ public class NodeDAO {
public
String
toString
()
{
return
relativePath
+
" "
+
path
;
}
public
String
getPath
()
{
return
this
.
path
;
}
public
String
getRelativePath
()
{
return
this
.
relativePath
;
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment