diff --git a/.classpath b/.classpath index 3ee7b9b..572d646 100644 --- a/.classpath +++ b/.classpath @@ -5,7 +5,7 @@ - + diff --git a/.gitignore b/.gitignore index 6885045..490d558 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ ivy.jar !/etc/ivy/ivysettings.xml *.secret archiva_credentials.xml +join-example-space.html +/frontend/ diff --git a/agent-developer.xml b/agent-developer.xml new file mode 100644 index 0000000..ba1cf91 --- /dev/null +++ b/agent-developer.xml @@ -0,0 +1,9 @@ + + f3ef36da93ea0875f840797d34cab1b2063df63107bb206238b46e92420f446453c6bb980b234a60986b3facd663cd6e416bcc49c60adca187922926c2bdf047 + rO0ABXNyABRqYXZhLnNlY3VyaXR5LktleVJlcL35T7OImqVDAgAETAAJYWxnb3JpdGhtdAASTGphdmEvbGFuZy9TdHJpbmc7WwAHZW5jb2RlZHQAAltCTAAGZm9ybWF0cQB+AAFMAAR0eXBldAAbTGphdmEvc2VjdXJpdHkvS2V5UmVwJFR5cGU7eHB0AANSU0F1cgACW0Ks8xf4BghU4AIAAHhwAAABJjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIAPE7NS9qdSf9RgZnPd2jCKemrXYNozq1VeQBOdzOOJucRKtnAOKrj+/h7IzYolZvcsra9D/NDewJu4T/luPMPSjnREBp0t/J5arUKyqcg5xbpR7bHEj+PccvlMxXncEuSBGl9eis7+5//eEH66MTDNj3wtdIqFMvSLHYDGZpfKLZ3P40AfRnAJjO8guGZDmBVa5PohdCToWm/isH+/lmqZb0/t2hmVBgG4AR4dN0FeslRfprVfK4b76HFOzxTq8rC41cB35JKVd23R8GL2fpdZBgWdvOFg/5rMxXu8RBHmSibyLf/0XIdEj8nYxHMqqJXDTmQFbmShhHUy7pO5OtkCAwEAAXQABVguNTA5fnIAGWphdmEuc2VjdXJpdHkuS2V5UmVwJFR5cGUAAAAAAAAAABIAAHhyAA5qYXZhLmxhbmcuRW51bQAAAAAAAAAAEgAAeHB0AAZQVUJMSUM= + + OuTHTH6uApSIdPvLyTGsMQ== + woXeiqUeFhrXyYvFYd+QMlK1rnI5mHIVmRFgshbQO4Sic6byDe/JF2LXpnRnP10G9tJAdQ7/yKzS7siostU08wGOCluACSJQC4Nt9zBDH9+fA8MTDyiaTVXjh78oW3wA0t9KLiY6iuYK9dZt2yMSdSa2eUO7ZtjolP10It9vemtInNTRXDxo1LmBHPoFm7eN0hHgasUflPQs9XfJ0JERGv/5+CfxuXiP3wg9SV7SnfkJUJCfxS8fmLadjGwthuexuNzUJqj/VYdBw2d3XKPQ53cFiC9j7miQOs+u8mlvX87FGO8tFlPwYzY+kfA1qOrdkszddzaCA4AQtD1jL5QzGixVR5C1EQ4I7k5LujHfYmSG2cja5p/Zm49ouTVmwe2mQI8mSoM91d/+RmQP1lYs5lND+dLegOiEfr71rssNHfoXHbqxlt6KT0E7l8ghUSgO6FrltH5J/DiETnSnpkfZ2I94lbEc6XMFojbyzqe7HucR9n926bOUcxwErFro+7NJLMtLMaBSdL5ECaPZjJAeAGq/odbW9hPoS2R9c44O1nXi+BaCJUvQBDetvXp4WS7uhxqUUJ8gcT/gJQbqGSrkA7kwvemL58wBgDJ9R2TlKmzWLKOA/dMfTc2F224v6Y0riHz7Uzx8VoZabysdDd/SN5FiRQGDQNyhFIPE4/TZ5YZhMJoarCCcHWKZH//bv2ZyAjuSY4yU+Q8xha/Fo9S8lqhYVfJqBzwq4nvo9M6htaP5n21fLEAO/dh88vNYB7KP3Lt/1nyrw4JfQ2ObHWfFhfWEBgJ8g85rSZT5yURjuM7fqY+3+befL9Y+VqShm7lRLxYQ0MUr4aunbrkBHCe4qIklHU6aVoKzfZlOkCK+13zspf/hzFCeiXqvE3mAzNYagjV0Bczpx9qzCfTSNM/E1AAqSNu8e8SpN0JwMJPqKnQ8zcO16lcwQR0Z/TPtUf3H+zALwvv2LojD9P4KdanvYEZ4jHPRgAYeQtp8sYrs4hAEoHPwp+q4QOpFaeSNj+8tnpZ3kQXdqT97bjfkVuD9MyZTEWnSHv5AKfvhqyDsglVt4KLg0lmFxtUWYwbu4preMC1Xm37Cinc2wf0ScS5/p949e7s+ZkOcwMElBT2Pe7gRPK3TDFuIM4jmzA5ExLc9i+EbofBtJPJmsYv+Kv5cT9/BUn7TbXIfgx1Np+6yi6MjS3Y8EOXyLJBL8CgK5XtfuSdyY8YjomFrKmpa5XmYwhK3bby226woLcGqWXaoUIPBk4M/YH6LWsmi2E/BOmN9qFP3So/xcAbo34cmO7zue7da+YKajz6QDzENj06wyg+EseahMXio4qGuD9j6OIZNl/Pqt+qFcaJXJYqjoP9wU2mwS1wzim8OxA+UlbdzRPqwsdU0yTrF5pmtxqFTQwofqgqQwNt0ZjFsTXMEpFqpIkVGDJrNuwu+S5x0spk7LqxXZX34sjdoCA8OxO3u+f9FxBQlFRTGiHfChxS+QbCdEmjxHUWNa41lgExL5tOe5DujHSmwzqCFra3H2cks3mrAyT0kJfS0J1TbijJVaaTUkGt2MUl7GUk/Sz9ZJq0aHBr18Ql1p/9lKCxGV1X+/9sF/Lr0lEefd4ST/YHA5DfZyZYwJNcphHcdmqF8mXwhxJ4JlaXIBw76/kMZLOH98npyTDmI6Dx+igRnbXXgd41BuW7RHgbRLIpC6gBuCnOUYuIqz6PAY7JpR1F7W5e3c3NIIUmm83mUmBaHBx9K/0DGau6oCj2zFOi94oAXkNjI9vUkiHIJVIkMxFfOmERtKHjqwGp17t50wXdgdAmMpekadj1yWX20zTHUf9US1r8yge12Dd3RDL9bjgUSY/BySMrnlgTCLKkJ4S6QZixYWUPryCUy8exHUxPIMbKIqZHKvRStUoFgn52B8y8+Pq3K1NCjlRj+pv+Xdo5E000a3stHGc7k8Svp4jdtrVFsSGRNDkUkKGIjW96CgwZZE7dprRoi + + developer + diff --git a/build.xml b/build.xml index 4362527..ae0bb4b 100644 --- a/build.xml +++ b/build.xml @@ -1,6 +1,6 @@ - + @@ -63,6 +63,7 @@ + diff --git a/launcher-configuration.ini b/launcher-configuration.ini index 5fb623b..518565b 100644 --- a/launcher-configuration.ini +++ b/launcher-configuration.ini @@ -9,10 +9,14 @@ service [commands] uploadStartupDirectory('example') +uploadServicePackage('service/i5.las2peer.services.fileService-2.2.0.jar', 'agent-developer.xml', 'topsecret') +startService('i5.las2peer.services.fileService.FileService@2.2.0','testtest') +uploadServicePackage('service/i5.las2peer.services.noracleService-0.5.0.jar', 'agent-developer.xml', 'topsecret') startService('i5.las2peer.services.noracleService.NoracleSpaceService@0.5.0','testtest') startService('i5.las2peer.services.noracleService.NoracleQuestionService@0.5.0','testtest') startService('i5.las2peer.services.noracleService.NoracleQuestionRelationService@0.5.0','testtest') startService('i5.las2peer.services.noracleService.NoracleAgentService@0.5.0','testtest') +startService('i5.las2peer.services.noracleService.NoracleVoteService@0.5.0','testtest') startService('i5.las2peer.services.noracleService.NoracleService@0.5.0','testtest') startWebConnector interactive diff --git a/noracle-generate-examples.sh b/noracle-generate-examples.sh index b1f737d..c390fd2 100755 --- a/noracle-generate-examples.sh +++ b/noracle-generate-examples.sh @@ -8,8 +8,8 @@ space_creator_agent_login="noracle-example-smith" agent_pw="testtest" num_spaces=5 -num_questions_per_space=50 -num_relations_per_space=25 +num_questions_per_space=25 +num_relations_per_space=15 relation_types=() relation_types+=("\"name\": \"Similarity\", \"directed\": \"false\"") @@ -27,18 +27,24 @@ random_lengthLorem() { # create example spaces -for num in {1..${num_spaces}}; do - curl -s -D - --user noracle-example-smith:${agent_pw} -X POST --header 'Content-Type: application/json' -d '{ "name": "example-space-'"${num}"'" }' "${endpoint}"'/spaces' --insecure +for (( num=1; num<=${num_spaces}; num++ )); do + curl -s -D - --user noracle-example-smith:${agent_pw} -X POST --header 'Content-Type: application/json' -d '{ "name": "example-space-'"${num}"'" }' "${endpoint}"'/spaces' --insecure & done +# wait till all requests terminated +wait # get all subscribed spaces for agent smith +example_space_ids=() +out="$( { curl -s --user noracle-example-smith:${agent_pw} -X GET --header 'Accept: application/json' "${endpoint}"'/agents/'"${space_creator_agent_id}"'/spacesubscriptions' --insecure ; } 2>&1 )" +while read spaceId ; do + example_space_ids+=("${spaceId}") +done < <(echo "${out}" | jq -r '.[].spaceId') -out="$( { curl -s --user noracle-example-smith:${agent_pw} -X GET --header 'Accept: application/json' "${endpoint}"'/agents/'"${space_creator_agent_id}"'/spacesubscriptions' --insecure ; } )" -echo "${out}" | jq -r '.[].spaceId' | while read spaceId ; do +for spaceId in "${example_space_ids[@]}" ; do # create questions inside space question_ids=() - for num in {1..${num_questions_per_space}}; do + for (( num=1; num<=${num_questions_per_space}; num++ )); do random=$(random_lengthLorem) out="$( { curl -s -D - --user noracle-example-smith:"${agent_pw}" -X POST --header 'Content-Type: application/json' -d '{ "text": "'"${random}"'" }' "${endpoint}"'/spaces/'"${spaceId}"'/questions' --insecure ; } 2>&1 )" echo "${out}" @@ -54,7 +60,7 @@ echo "${out}" | jq -r '.[].spaceId' | while read spaceId ; do question_ids+=(${question_id}) done # create random relations between questions - for num in {1..${num_relations_per_space}}; do + for (( num=1; num<=${num_relations_per_space}; num++ )); do relation_type=${relation_types[$RANDOM % ${#relation_types[@]} ]} first_question_id=${question_ids[$RANDOM % ${#question_ids[@]} ]} second_question_id=${question_ids[$RANDOM % ${#question_ids[@]} ]} @@ -63,3 +69,28 @@ echo "${out}" | jq -r '.[].spaceId' | while read spaceId ; do done done +# generate join links +space_join_links="" +for spaceId in "${example_space_ids[@]}" ; do + out="$( { curl -s -D - --user noracle-example-smith:${agent_pw} -X GET --header 'Accept: application/json' "${endpoint}"'/spaces/'"${spaceId}" --insecure ; } 2>&1 )" + while read spaceSecret ; do + space_join_links="${space_join_links}" + done < <(echo "${out}" | jq -r '.spaceSecret') +done + +# write invitation links to file +read -d '' join_space_file_content <<- EOF + + +Join A Noracle Example Space + + +

Please click on a link below to join the appropriate Noracle example space

+${space_join_links} + + + +EOF + +echo "${join_space_file_content}" > "join-example-space.html" + diff --git a/src/main/i5/las2peer/services/noracleService/NoracleAgentService.java b/src/main/i5/las2peer/services/noracleService/NoracleAgentService.java index 849febc..5ccb79f 100755 --- a/src/main/i5/las2peer/services/noracleService/NoracleAgentService.java +++ b/src/main/i5/las2peer/services/noracleService/NoracleAgentService.java @@ -24,7 +24,8 @@ /** * Noracle Agents Service * - * This service is used to handle agents metadata in a distributed Noracle system. + * This service is used to handle agents metadata in a distributed Noracle + * system. * */ public class NoracleAgentService extends Service implements INoracleAgentService { @@ -124,10 +125,6 @@ public SpaceSubscriptionList getSpaceSubscriptions(String agentId) throws Servic } } - private String buildSubscriptionId(String agentId) { - return "spacesubscriptions-" + agentId; - } - @Override public SpaceSubscription updateSpaceSubscription(String agentId, String spaceId, String[] selectedQuestions) throws ServiceInvocationException { @@ -162,8 +159,58 @@ public SpaceSubscription updateSpaceSubscription(String agentId, String spaceId, @Override public NoracleAgentProfile updateAgentProfile(String agentName) throws ServiceInvocationException { - // TODO Implement (create or update should both be done here) - return null; + Agent mainAgent = Context.get().getMainAgent(); + String envIdentifier = buildAgentProfileId(mainAgent.getIdentifier()); + Envelope env; + NoracleAgentProfile profile; + // look for existing profile, otherwise create one + try { + try { + env = Context.get().requestEnvelope(envIdentifier); + profile = (NoracleAgentProfile) env.getContent(); + } catch (EnvelopeNotFoundException e) { + env = Context.get().createEnvelope(envIdentifier); + profile = new NoracleAgentProfile(); + } + } catch (EnvelopeAccessDeniedException e) { + throw new ServiceAccessDeniedException("Envelope access denied"); + } catch (EnvelopeOperationFailedException e) { + throw new InternalServiceException("Could not create new envelope for noracle agent profile", e); + } + profile.setName(agentName); + env.setContent(profile); + env.setPublic(); + try { + Context.get().storeEnvelope(env, mainAgent); + } catch (EnvelopeAccessDeniedException e) { + throw new ServiceAccessDeniedException("Envelope access denied"); + } catch (EnvelopeOperationFailedException e) { + throw new InternalServiceException("Storing envelope with noracle agent profile failed", e); + } + return profile; + } + + @Override + public NoracleAgentProfile getAgentProfile(String agentId) throws ServiceInvocationException { + String envIdentifier = buildAgentProfileId(agentId); + try { + Envelope env = Context.get().requestEnvelope(envIdentifier); + return (NoracleAgentProfile) env.getContent(); + } catch (EnvelopeAccessDeniedException e) { + throw new ServiceAccessDeniedException("Envelope access denied"); + } catch (EnvelopeOperationFailedException e) { + throw new InternalServiceException("Could not fetch agent profile", e); + } catch (EnvelopeNotFoundException e) { + return new NoracleAgentProfile(); + } + } + + private String buildSubscriptionId(String agentId) { + return "spacesubscriptions-" + agentId; + } + + private String buildAgentProfileId(String agentId) { + return "noracleagentprofile-" + agentId; } } diff --git a/src/main/i5/las2peer/services/noracleService/NoracleService.java b/src/main/i5/las2peer/services/noracleService/NoracleService.java index 77ca23a..effddef 100644 --- a/src/main/i5/las2peer/services/noracleService/NoracleService.java +++ b/src/main/i5/las2peer/services/noracleService/NoracleService.java @@ -14,14 +14,7 @@ import io.swagger.annotations.SwaggerDefinition; @Api -@SwaggerDefinition( - info = @Info( - title = "Noracle Service", - version = NoracleService.API_VERSION, - description = "A bundle service for the distributed Noracle system", - license = @License( - name = "BSD-3", - url = "https://github.com/rwth-acis/Noracle-Bundle-Service/blob/master/LICENSE"))) +@SwaggerDefinition(info = @Info(title = "Noracle Service", version = NoracleService.API_VERSION, description = "A bundle service for the distributed Noracle system", license = @License(name = "BSD-3", url = "https://github.com/Distributed-Noracle/Distributed-Noracle-Backend/blob/master/LICENSE.txt"))) @ServicePath("/" + NoracleService.RESOURCE_NAME) public class NoracleService extends RESTService { diff --git a/src/main/i5/las2peer/services/noracleService/NoracleVoteService.java b/src/main/i5/las2peer/services/noracleService/NoracleVoteService.java index a219c2a..0eb1ae9 100644 --- a/src/main/i5/las2peer/services/noracleService/NoracleVoteService.java +++ b/src/main/i5/las2peer/services/noracleService/NoracleVoteService.java @@ -22,7 +22,7 @@ public class NoracleVoteService extends Service implements INoracleVoteService { private static final int MAX_VOTES_PER_OBJECT = 1000000; @Override - public void setVote(String agentId, String objectId, int vote) throws ServiceInvocationException { + public Vote setVote(String agentId, String objectId, int vote) throws ServiceInvocationException { Agent mainAgent = Context.get().getMainAgent(); if (objectId == null || objectId.isEmpty()) { throw new InvocationBadArgumentException("No object id given"); @@ -41,6 +41,7 @@ public void setVote(String agentId, String objectId, int vote) throws ServiceInv voteEntry.setVote(pubVote); persEnv.setContent(voteEntry); Context.get().storeEnvelope(persEnv); + return pubVote; } catch (EnvelopeNotFoundException e) { Envelope persEnv = Context.get().createEnvelope(persEnvId); String pubEnvId = null; @@ -66,6 +67,7 @@ public void setVote(String agentId, String objectId, int vote) throws ServiceInv VoteEntry voteEntry = new VoteEntry(objectId, pubIndex, pubVote); persEnv.setContent(voteEntry); Context.get().storeEnvelope(persEnv); + return pubVote; } } catch (EnvelopeAccessDeniedException e) { throw new ServiceAccessDeniedException("Envelope Access Denied"); diff --git a/src/main/i5/las2peer/services/noracleService/api/INoracleAgentService.java b/src/main/i5/las2peer/services/noracleService/api/INoracleAgentService.java index da06ccc..ccdc7e3 100644 --- a/src/main/i5/las2peer/services/noracleService/api/INoracleAgentService.java +++ b/src/main/i5/las2peer/services/noracleService/api/INoracleAgentService.java @@ -9,6 +9,8 @@ public interface INoracleAgentService { public NoracleAgentProfile updateAgentProfile(String agentName) throws ServiceInvocationException; + public NoracleAgentProfile getAgentProfile(String agentId) throws ServiceInvocationException; + public SpaceSubscription subscribeToSpace(String spaceId, String spaceSecret) throws ServiceInvocationException; public void unsubscribeFromSpace(String spaceId) throws ServiceInvocationException; diff --git a/src/main/i5/las2peer/services/noracleService/api/INoracleVoteService.java b/src/main/i5/las2peer/services/noracleService/api/INoracleVoteService.java index 8676324..03432e5 100644 --- a/src/main/i5/las2peer/services/noracleService/api/INoracleVoteService.java +++ b/src/main/i5/las2peer/services/noracleService/api/INoracleVoteService.java @@ -6,7 +6,7 @@ public interface INoracleVoteService { - public void setVote(String agentId, String objectId, int value) throws ServiceInvocationException; + public Vote setVote(String agentId, String objectId, int value) throws ServiceInvocationException; public Vote getAgentVote(String objectId, String agentId) throws ServiceInvocationException; diff --git a/src/main/i5/las2peer/services/noracleService/model/NoracleAgentProfile.java b/src/main/i5/las2peer/services/noracleService/model/NoracleAgentProfile.java index 5c67234..634a42e 100644 --- a/src/main/i5/las2peer/services/noracleService/model/NoracleAgentProfile.java +++ b/src/main/i5/las2peer/services/noracleService/model/NoracleAgentProfile.java @@ -1,6 +1,10 @@ package i5.las2peer.services.noracleService.model; -public class NoracleAgentProfile { +import java.io.Serializable; + +public class NoracleAgentProfile implements Serializable { + + private static final long serialVersionUID = 1L; private String name; public String getName() { diff --git a/src/main/i5/las2peer/services/noracleService/pojo/CreateProfilePojo.java b/src/main/i5/las2peer/services/noracleService/pojo/ChangeProfilePojo.java similarity index 86% rename from src/main/i5/las2peer/services/noracleService/pojo/CreateProfilePojo.java rename to src/main/i5/las2peer/services/noracleService/pojo/ChangeProfilePojo.java index 11ef736..fe89e80 100644 --- a/src/main/i5/las2peer/services/noracleService/pojo/CreateProfilePojo.java +++ b/src/main/i5/las2peer/services/noracleService/pojo/ChangeProfilePojo.java @@ -1,6 +1,6 @@ package i5.las2peer.services.noracleService.pojo; -public class CreateProfilePojo { +public class ChangeProfilePojo { private String agentName; public String getAgentName() { diff --git a/src/main/i5/las2peer/services/noracleService/resources/AgentsResource.java b/src/main/i5/las2peer/services/noracleService/resources/AgentsResource.java index 61e6f4e..9347de3 100644 --- a/src/main/i5/las2peer/services/noracleService/resources/AgentsResource.java +++ b/src/main/i5/las2peer/services/noracleService/resources/AgentsResource.java @@ -29,15 +29,14 @@ import i5.las2peer.services.noracleService.model.NoracleAgentProfile; import i5.las2peer.services.noracleService.model.SpaceSubscription; import i5.las2peer.services.noracleService.model.SpaceSubscriptionList; -import i5.las2peer.services.noracleService.pojo.CreateProfilePojo; +import i5.las2peer.services.noracleService.pojo.ChangeProfilePojo; import i5.las2peer.services.noracleService.pojo.SubscribeSpacePojo; import i5.las2peer.services.noracleService.pojo.UpdateSelectedQuestionsPojo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; -@Api( - tags = { AgentsResource.RESOURCE_NAME }) +@Api(tags = { AgentsResource.RESOURCE_NAME }) public class AgentsResource implements INoracleAgentService { public static final String RESOURCE_NAME = "agents"; @@ -46,25 +45,11 @@ public class AgentsResource implements INoracleAgentService { @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_HTML) - @ApiResponses({ @ApiResponse( - code = HttpURLConnection.HTTP_CREATED, - message = "Subscription successfully created"), - @ApiResponse( - code = HttpURLConnection.HTTP_BAD_REQUEST, - message = "No space id given", - response = ExceptionEntity.class), - @ApiResponse( - code = HttpURLConnection.HTTP_UNAUTHORIZED, - message = "You have to be logged in to subscribe to a space", - response = ExceptionEntity.class), - @ApiResponse( - code = HttpURLConnection.HTTP_FORBIDDEN, - message = "You can only subscribe yourself to a space", - response = ExceptionEntity.class), - @ApiResponse( - code = HttpURLConnection.HTTP_INTERNAL_ERROR, - message = "Internal Server Error", - response = ExceptionEntity.class) }) + @ApiResponses({ @ApiResponse(code = HttpURLConnection.HTTP_CREATED, message = "Subscription successfully created"), + @ApiResponse(code = HttpURLConnection.HTTP_BAD_REQUEST, message = "No space id given", response = ExceptionEntity.class), + @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "You have to be logged in to subscribe to a space", response = ExceptionEntity.class), + @ApiResponse(code = HttpURLConnection.HTTP_FORBIDDEN, message = "You can only subscribe yourself to a space", response = ExceptionEntity.class), + @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal Server Error", response = ExceptionEntity.class) }) @Path("/" + SUBSCRIPTIONS_RESOURCE_NAME) public Response subscribeToSpace(@PathParam("agentid") String agentId, SubscribeSpacePojo subscribeSpacePojo) throws ServiceInvocationException { @@ -96,33 +81,18 @@ public SpaceSubscription subscribeToSpace(String spaceId, String spaceSecret) th @PUT @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_HTML) - @ApiResponses({ @ApiResponse( - code = HttpURLConnection.HTTP_OK, - message = "Agent successfully updated"), - @ApiResponse( - code = HttpURLConnection.HTTP_UNAUTHORIZED, - message = "You have to be logged in to update your profile", - response = ExceptionEntity.class), - @ApiResponse( - code = HttpURLConnection.HTTP_FORBIDDEN, - message = "You can only update your own profile", - response = ExceptionEntity.class), - @ApiResponse( - code = HttpURLConnection.HTTP_INTERNAL_ERROR, - message = "Internal Server Error", - response = ExceptionEntity.class) }) - public Response updateAgentProfile(@PathParam("agentid") String agentId, CreateProfilePojo createProfilePojo) - throws ServiceInvocationException { + @Produces(MediaType.APPLICATION_JSON) + @ApiResponses({ + @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Agent successfully updated", response = NoracleAgentProfile.class), + @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "You have to be logged in to update your profile", response = ExceptionEntity.class), + @ApiResponse(code = HttpURLConnection.HTTP_FORBIDDEN, message = "You can only update your own profile", response = ExceptionEntity.class), + @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal Server Error", response = ExceptionEntity.class) }) + public NoracleAgentProfile updateAgentProfile(@PathParam("agentid") String agentId, + ChangeProfilePojo createProfilePojo) throws ServiceInvocationException { if (!Context.get().getMainAgent().getIdentifier().equals(agentId)) { throw new ForbiddenException("Only update your own profile"); } - updateAgentProfile(createProfilePojo.getAgentName()); - try { - return Response.ok(new URI(null, null, RESOURCE_NAME + "/" + agentId, null)).build(); - } catch (URISyntaxException e) { - throw new InternalServerErrorException(e); - } + return updateAgentProfile(createProfilePojo.getAgentName()); } @Override @@ -138,27 +108,48 @@ public NoracleAgentProfile updateAgentProfile(String agentName) throws ServiceIn } } + @GET + @Produces(MediaType.APPLICATION_JSON) + @ApiResponses({ + @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Agent profile successfully fetched", response = NoracleAgentProfile.class), + @ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = "Agent profile was not found", response = ExceptionEntity.class), + @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal Server Error", response = ExceptionEntity.class) }) + public Response getAgentProfileWeb(@PathParam("agentid") String agentId) throws ServiceInvocationException { + Serializable rmiResult = Context.get().invoke( + new ServiceNameVersion(NoracleAgentService.class.getCanonicalName(), NoracleService.API_VERSION), + "getAgentProfile", agentId); + if (rmiResult instanceof NoracleAgentProfile) { + NoracleAgentProfile profile = getAgentProfile(agentId); + if (profile.getName() == null) { + return Response.status(Response.Status.NOT_FOUND).build(); + } + return Response.ok(profile).build(); + } else { + throw new InternalServiceException( + "Unexpected result (" + rmiResult.getClass().getCanonicalName() + ") of RMI call"); + } + } + + @Override + public NoracleAgentProfile getAgentProfile(String agentId) throws ServiceInvocationException { + Serializable rmiResult = Context.get().invoke( + new ServiceNameVersion(NoracleAgentService.class.getCanonicalName(), NoracleService.API_VERSION), + "getAgentProfile", agentId); + if (rmiResult instanceof NoracleAgentProfile) { + return (NoracleAgentProfile) rmiResult; + } else { + throw new InternalServiceException( + "Unexpected result (" + rmiResult.getClass().getCanonicalName() + ") of RMI call"); + } + } + @DELETE @Produces(MediaType.TEXT_HTML) - @ApiResponses({ @ApiResponse( - code = HttpURLConnection.HTTP_OK, - message = "Unsubscribed from space"), - @ApiResponse( - code = HttpURLConnection.HTTP_BAD_REQUEST, - message = "No space id given", - response = ExceptionEntity.class), - @ApiResponse( - code = HttpURLConnection.HTTP_UNAUTHORIZED, - message = "You have to be logged in to unsubscribe from a space", - response = ExceptionEntity.class), - @ApiResponse( - code = HttpURLConnection.HTTP_FORBIDDEN, - message = "You can only unsubscribe yourself from a space", - response = ExceptionEntity.class), - @ApiResponse( - code = HttpURLConnection.HTTP_INTERNAL_ERROR, - message = "Internal Server Error", - response = ExceptionEntity.class) }) + @ApiResponses({ @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Unsubscribed from space"), + @ApiResponse(code = HttpURLConnection.HTTP_BAD_REQUEST, message = "No space id given", response = ExceptionEntity.class), + @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "You have to be logged in to unsubscribe from a space", response = ExceptionEntity.class), + @ApiResponse(code = HttpURLConnection.HTTP_FORBIDDEN, message = "You can only unsubscribe yourself from a space", response = ExceptionEntity.class), + @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal Server Error", response = ExceptionEntity.class) }) @Path("/" + SUBSCRIPTIONS_RESOURCE_NAME + "/{spaceId}") public Response unsubscribeFromSpace(@PathParam("agentid") String agentId, @PathParam("spaceId") String spaceId) throws ServiceInvocationException { @@ -179,14 +170,9 @@ public void unsubscribeFromSpace(String spaceId) throws ServiceInvocationExcepti @Override @GET @Produces(MediaType.APPLICATION_JSON) - @ApiResponses({ @ApiResponse( - code = HttpURLConnection.HTTP_OK, - message = "Subscriptions successfully fetched", - response = SpaceSubscriptionList.class), - @ApiResponse( - code = HttpURLConnection.HTTP_INTERNAL_ERROR, - message = "Internal Server Error", - response = ExceptionEntity.class) }) + @ApiResponses({ + @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Subscriptions successfully fetched", response = SpaceSubscriptionList.class), + @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal Server Error", response = ExceptionEntity.class) }) @Path("/" + SUBSCRIPTIONS_RESOURCE_NAME) public SpaceSubscriptionList getSpaceSubscriptions(@PathParam("agentid") String agentId) throws ServiceInvocationException { @@ -204,14 +190,9 @@ public SpaceSubscriptionList getSpaceSubscriptions(@PathParam("agentid") String @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @ApiResponses({ @ApiResponse( - code = HttpURLConnection.HTTP_OK, - message = "Selected questions successfully updated", - response = SpaceSubscription.class), - @ApiResponse( - code = HttpURLConnection.HTTP_INTERNAL_ERROR, - message = "Internal Server Error", - response = ExceptionEntity.class) }) + @ApiResponses({ + @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "Selected questions successfully updated", response = SpaceSubscription.class), + @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal Server Error", response = ExceptionEntity.class) }) @Path("/" + SUBSCRIPTIONS_RESOURCE_NAME + "/{spaceId}/selectedQuestions") public SpaceSubscription updateSelectedQuestions(@PathParam("agentid") String agentId, @PathParam("spaceId") String spaceId, UpdateSelectedQuestionsPojo updateSelectedQuestionsPojo) diff --git a/src/main/i5/las2peer/services/noracleService/resources/QuestionVotesResource.java b/src/main/i5/las2peer/services/noracleService/resources/QuestionVotesResource.java index 9b2b32d..372e12d 100644 --- a/src/main/i5/las2peer/services/noracleService/resources/QuestionVotesResource.java +++ b/src/main/i5/las2peer/services/noracleService/resources/QuestionVotesResource.java @@ -10,7 +10,6 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import i5.las2peer.api.Context; import i5.las2peer.api.execution.InternalServiceException; @@ -36,10 +35,11 @@ public class QuestionVotesResource implements INoracleVoteService { @PUT @Path("/{agentId}") @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_HTML) + @Produces(MediaType.APPLICATION_JSON) @ApiResponses({ @ApiResponse( code = HttpURLConnection.HTTP_OK, - message = "Vote successfully set"), + message = "Vote successfully set", + response = Vote.class), @ApiResponse( code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "You have to be logged in to vote", @@ -48,18 +48,23 @@ public class QuestionVotesResource implements INoracleVoteService { code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal Server Error", response = ExceptionEntity.class) }) - public Response putSetVote(@PathParam("spaceId") String spaceId, @PathParam("questionId") String questionId, + public Vote putSetVote(@PathParam("spaceId") String spaceId, @PathParam("questionId") String questionId, @PathParam("agentId") String agentId, SetVotePojo setVotePojo) throws ServiceInvocationException { String objectId = buildObjectId(spaceId, questionId); - setVote(agentId, objectId, setVotePojo.getValue()); - return Response.ok().build(); + return setVote(agentId, objectId, setVotePojo.getValue()); } @Override - public void setVote(String agentId, String objectId, int value) throws ServiceInvocationException { - Context.get().invoke( + public Vote setVote(String agentId, String objectId, int value) throws ServiceInvocationException { + Serializable rmiResult = Context.get().invoke( new ServiceNameVersion(NoracleVoteService.class.getCanonicalName(), NoracleService.API_VERSION), "setVote", agentId, objectId, value); + if (rmiResult instanceof Vote) { + return (Vote) rmiResult; + } else { + throw new InternalServiceException( + "Unexpected result (" + rmiResult.getClass().getCanonicalName() + ") of RMI call"); + } } @GET diff --git a/src/main/i5/las2peer/services/noracleService/resources/RelationVotesResource.java b/src/main/i5/las2peer/services/noracleService/resources/RelationVotesResource.java index ff9e0d8..efa701b 100644 --- a/src/main/i5/las2peer/services/noracleService/resources/RelationVotesResource.java +++ b/src/main/i5/las2peer/services/noracleService/resources/RelationVotesResource.java @@ -10,7 +10,6 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import i5.las2peer.api.Context; import i5.las2peer.api.execution.InternalServiceException; @@ -36,10 +35,11 @@ public class RelationVotesResource implements INoracleVoteService { @PUT @Path("/{agentId}") @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.TEXT_HTML) + @Produces(MediaType.APPLICATION_JSON) @ApiResponses({ @ApiResponse( code = HttpURLConnection.HTTP_OK, - message = "Vote successfully set"), + message = "Vote successfully set", + response = Vote.class), @ApiResponse( code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "You have to be logged in to vote", @@ -48,18 +48,23 @@ public class RelationVotesResource implements INoracleVoteService { code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal Server Error", response = ExceptionEntity.class) }) - public Response putSetVote(@PathParam("spaceId") String spaceId, @PathParam("relationId") String relationId, + public Vote putSetVote(@PathParam("spaceId") String spaceId, @PathParam("relationId") String relationId, @PathParam("agentId") String agentId, SetVotePojo setVotePojo) throws ServiceInvocationException { String objectId = buildObjectId(spaceId, relationId); - setVote(agentId, objectId, setVotePojo.getValue()); - return Response.ok().build(); + return setVote(agentId, objectId, setVotePojo.getValue()); } @Override - public void setVote(String agentId, String objectId, int value) throws ServiceInvocationException { - Context.get().invoke( + public Vote setVote(String agentId, String objectId, int value) throws ServiceInvocationException { + Serializable rmiResult = Context.get().invoke( new ServiceNameVersion(NoracleVoteService.class.getCanonicalName(), NoracleService.API_VERSION), "setVote", agentId, objectId, value); + if (rmiResult instanceof Vote) { + return (Vote) rmiResult; + } else { + throw new InternalServiceException( + "Unexpected result (" + rmiResult.getClass().getCanonicalName() + ") of RMI call"); + } } @GET diff --git a/src/test/i5/las2peer/services/noracleService/NoracleServiceTest.java b/src/test/i5/las2peer/services/noracleService/NoracleServiceTest.java index cfc3f2d..a0db95e 100644 --- a/src/test/i5/las2peer/services/noracleService/NoracleServiceTest.java +++ b/src/test/i5/las2peer/services/noracleService/NoracleServiceTest.java @@ -27,6 +27,7 @@ import i5.las2peer.p2p.PastryNodeImpl; import i5.las2peer.security.ServiceAgentImpl; import i5.las2peer.security.UserAgentImpl; +import i5.las2peer.services.noracleService.model.NoracleAgentProfile; import i5.las2peer.services.noracleService.model.Question; import i5.las2peer.services.noracleService.model.QuestionList; import i5.las2peer.services.noracleService.model.QuestionRelation; @@ -35,6 +36,7 @@ import i5.las2peer.services.noracleService.model.SpaceSubscriptionList; import i5.las2peer.services.noracleService.model.Vote; import i5.las2peer.services.noracleService.model.VoteList; +import i5.las2peer.services.noracleService.pojo.ChangeProfilePojo; import i5.las2peer.services.noracleService.pojo.ChangeQuestionPojo; import i5.las2peer.services.noracleService.pojo.CreateQuestionPojo; import i5.las2peer.services.noracleService.pojo.CreateRelationPojo; @@ -71,7 +73,8 @@ public void beforeTest() { nodes = TestSuite.launchNetwork(networkSize); connector = new WebConnector(null); connector.start(nodes.get(0)); - // don't follow redirects, some tests want to test for correct redirect responses + // don't follow redirects, some tests want to test for correct redirect + // responses webClient = ClientBuilder.newBuilder().register(MultiPartFeature.class) .property(ClientProperties.FOLLOW_REDIRECTS, Boolean.FALSE).build(); startService(nodes.get(0), "i5.las2peer.services.noracleService.NoracleService", @@ -109,6 +112,7 @@ private void startService(Node node, String clsName, String version) throws Exce ServiceAgentImpl serviceAgent = ServiceAgentImpl.createServiceAgent(new ServiceNameVersion(clsName, version), "testtest"); serviceAgent.unlock("testtest"); + node.storeAgent(serviceAgent); node.registerReceiver(serviceAgent); } @@ -191,9 +195,9 @@ public void testAutoSubscribe() { Response response = request.get(); Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus()); Assert.assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getMediaType()); - SpaceSubscriptionList result2 = response.readEntity(SpaceSubscriptionList.class); - Assert.assertEquals(result2.size(), 1); - Assert.assertEquals(testSpaceId, result2.get(0).getSpaceId()); + SpaceSubscriptionList result = response.readEntity(SpaceSubscriptionList.class); + Assert.assertEquals(result.size(), 1); + Assert.assertEquals(testSpaceId, result.get(0).getSpaceId()); } catch (Exception e) { e.printStackTrace(); Assert.fail(e.toString()); @@ -202,7 +206,62 @@ public void testAutoSubscribe() { @Test public void testAgentProfile() { - // TODO TEST + try { + // first update the sample agent with a new name + ChangeProfilePojo body = new ChangeProfilePojo(); + body.setAgentName("Test Name"); + WebTarget target = webClient + .target(baseUrl + "/" + AgentsResource.RESOURCE_NAME + "/" + testAgent.getIdentifier()); + Builder request = target.request().header(HttpHeaders.AUTHORIZATION, basicAuthHeader); + Response response = request.put(Entity.json(body)); + Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus()); + Assert.assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getMediaType()); + NoracleAgentProfile result = response.readEntity(NoracleAgentProfile.class); + Assert.assertEquals("Test Name", result.getName()); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail(e.toString()); + } + try { + // now retrieve it + WebTarget target = webClient + .target(baseUrl + "/" + AgentsResource.RESOURCE_NAME + "/" + testAgent.getIdentifier()); + Builder request = target.request().header(HttpHeaders.AUTHORIZATION, basicAuthHeader); + Response response = request.get(); + Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus()); + Assert.assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getMediaType()); + NoracleAgentProfile result = response.readEntity(NoracleAgentProfile.class); + Assert.assertEquals("Test Name", result.getName()); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail(e.toString()); + } + try { + // test to read it with another agent + WebTarget target = webClient + .target(baseUrl + "/" + AgentsResource.RESOURCE_NAME + "/" + testAgent.getIdentifier()); + Builder request = target.request().header(HttpHeaders.AUTHORIZATION, basicAuthHeader2); + Response response = request.get(); + Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus()); + Assert.assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getMediaType()); + NoracleAgentProfile result = response.readEntity(NoracleAgentProfile.class); + Assert.assertEquals("Test Name", result.getName()); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail(e.toString()); + } + try { + // now test a not yet created profile: + WebTarget target = webClient + .target(baseUrl + "/" + AgentsResource.RESOURCE_NAME + "/" + testAgent2.getIdentifier()); + Builder request = target.request().header(HttpHeaders.AUTHORIZATION, basicAuthHeader); + Response response = request.get(); + Assert.assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus()); + Assert.assertEquals(MediaType.TEXT_HTML_TYPE, response.getMediaType()); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail(e.toString()); + } } @Test @@ -591,7 +650,7 @@ private void setVote(String path, String authHeader, int value) { Builder request = target.request().header(HttpHeaders.AUTHORIZATION, authHeader); Response response = request.put(Entity.json(body)); Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus()); - Assert.assertEquals(MediaType.TEXT_HTML_TYPE, response.getMediaType()); + Assert.assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getMediaType()); } private Vote getAgentVote(String path) { diff --git a/upload-frontend.sh b/upload-frontend.sh new file mode 100755 index 0000000..aa17bf1 --- /dev/null +++ b/upload-frontend.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +cd frontend && find "noracle/" -type f -exec curl --user "noracle-example-smith:testtest" --form "filecontent=@{};filename={}" --form identifier="{}" http://localhost:9082/fileservice/files --insecure \;