├── .classpath
├── .gitignore
├── .project
├── .settings
├── org.eclipse.jdt.core.prefs
├── org.eclipse.ltk.core.refactoring.prefs
└── org.eclipse.m2e.core.prefs
├── AUTHORS
├── LICENSE
├── README.md
├── config.properties
├── packaging
├── common
│ ├── stacksync-server
│ └── stacksync-server.1.gz
└── debian
│ ├── Makefile
│ └── debian
│ ├── changelog
│ ├── compat
│ ├── conffiles
│ ├── control
│ ├── dirs
│ ├── postinst
│ ├── postrm
│ ├── prerm
│ └── stacksync-server.init
├── pom.xml
├── script
├── adduser.sh
└── install_deps.sh
└── src
├── main
├── java
│ └── com
│ │ └── stacksync
│ │ └── syncservice
│ │ ├── SyncServiceDaemon.java
│ │ ├── db
│ │ ├── ConnectionPool.java
│ │ ├── ConnectionPoolFactory.java
│ │ ├── DAOError.java
│ │ ├── DAOFactory.java
│ │ ├── DAOUtil.java
│ │ ├── DeviceDAO.java
│ │ ├── ItemDAO.java
│ │ ├── ItemVersionDAO.java
│ │ ├── UserDAO.java
│ │ ├── WorkspaceDAO.java
│ │ └── postgresql
│ │ │ ├── PostgresqlConnectionPool.java
│ │ │ ├── PostgresqlDAO.java
│ │ │ ├── PostgresqlDeviceDAO.java
│ │ │ ├── PostgresqlItemDAO.java
│ │ │ ├── PostgresqlItemVersionDao.java
│ │ │ ├── PostgresqlUserDAO.java
│ │ │ └── PostgresqlWorkspaceDAO.java
│ │ ├── exceptions
│ │ ├── CommitExistantVersion.java
│ │ ├── CommitWrongVersion.java
│ │ ├── InternalServerError.java
│ │ ├── InvalidReader.java
│ │ ├── NotEnoughConsumersException.java
│ │ ├── dao
│ │ │ ├── DAOConfigurationException.java
│ │ │ ├── DAOException.java
│ │ │ ├── NoGeneratedKeysDAOException.java
│ │ │ ├── NoResultReturnedDAOException.java
│ │ │ └── NoRowsAffectedDAOException.java
│ │ └── storage
│ │ │ ├── EndpointNotFoundException.java
│ │ │ ├── NoStorageManagerAvailable.java
│ │ │ ├── ObjectNotFoundException.java
│ │ │ ├── UnauthorizedException.java
│ │ │ └── UnexpectedStatusCodeException.java
│ │ ├── handler
│ │ ├── APIHandler.java
│ │ ├── Handler.java
│ │ ├── SQLAPIHandler.java
│ │ ├── SQLSyncHandler.java
│ │ ├── SyncHandler.java
│ │ └── UnshareData.java
│ │ ├── omq
│ │ └── SyncServiceImp.java
│ │ ├── rpc
│ │ ├── Reader.java
│ │ ├── XmlRpcRequestHandlerFactory.java
│ │ ├── XmlRpcSyncHandler.java
│ │ ├── XmlRpcSyncServer.java
│ │ ├── messages
│ │ │ ├── APICommitResponse.java
│ │ │ ├── APICreateFolderResponse.java
│ │ │ ├── APIDeleteResponse.java
│ │ │ ├── APIGetFolderMembersResponse.java
│ │ │ ├── APIGetMetadata.java
│ │ │ ├── APIGetVersions.java
│ │ │ ├── APIGetWorkspaceInfoResponse.java
│ │ │ ├── APIResponse.java
│ │ │ ├── APIRestoreMetadata.java
│ │ │ ├── APIShareFolderResponse.java
│ │ │ ├── APIUnshareFolderResponse.java
│ │ │ └── APIUserMetadata.java
│ │ └── parser
│ │ │ ├── IParser.java
│ │ │ └── JSONParser.java
│ │ ├── storage
│ │ ├── StorageFactory.java
│ │ ├── StorageManager.java
│ │ ├── SwiftManager.java
│ │ ├── SwiftManagerHTTPS.java
│ │ ├── SwiftResponse.java
│ │ └── swift
│ │ │ ├── AccessObject.java
│ │ │ ├── EndpointObject.java
│ │ │ ├── LoginResponseObject.java
│ │ │ ├── ServiceObject.java
│ │ │ └── TokenObject.java
│ │ └── util
│ │ ├── CleanObjects.java
│ │ ├── Config.java
│ │ └── Constants.java
└── resources
│ ├── example.properties
│ ├── log4j.xml
│ ├── setup_db.sql
│ └── version.properties
└── test
└── java
└── com
└── stacksync
└── syncservice
└── test
├── benchmark
├── Constants.java
├── DBBenchmark.java
├── MetadataGenerator.java
├── db
│ └── DatabaseHelper.java
├── normal
│ ├── CommonFunctions.java
│ ├── RandomString.java
│ ├── TestCommit.java
│ ├── TestGetChanges.java
│ └── TestGetWorkspaces.java
└── omq
│ ├── RabbitConfig.java
│ ├── TestCommit.java
│ ├── TestGetChanges.java
│ └── TestGetWorkspaces.java
├── dao
└── PostgresqlDAOTest.java
├── handler
├── AdvancedHandlerTest.java
├── BasicHandlerTest.java
├── CreateFileTest.java
├── GetMetadataTest.java
├── GetWorkspaceInfoTest.java
├── SendShareNotificationTest.java
├── ShareFolderTest.java
├── SharingTest.java
├── UpdateDataTest.java
├── UpdateDeviceTest.java
└── UpdateMetadataTest.java
├── main
└── ServerTest.java
├── reader
└── JSONParserTest.java
└── xmlrpc
├── ApiCreateFolder.java
├── ApiDeleteMetadataFile.java
├── ApiGetMetadata.java
├── ApiGetVersions.java
├── ApiPutMetadataFile.java
├── ApiPutMetadataFolder.java
├── ApiRestoreMetadata.java
└── Constants.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Package Files #
4 | *.jar
5 | *.war
6 | *.ear
7 | /target/
8 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | sync-service
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.m2e.core.maven2Builder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.m2e.core.maven2Nature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
3 | org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
4 | org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
5 | org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
6 | org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
7 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
8 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
9 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
10 | org.eclipse.jdt.core.compiler.compliance=1.6
11 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
12 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
13 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
14 | org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
15 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
16 | org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
17 | org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
18 | org.eclipse.jdt.core.compiler.problem.deadCode=warning
19 | org.eclipse.jdt.core.compiler.problem.deprecation=warning
20 | org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
21 | org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
22 | org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
23 | org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
24 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
25 | org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
26 | org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
27 | org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
28 | org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
29 | org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
30 | org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
31 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
32 | org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
33 | org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
34 | org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
35 | org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
36 | org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
37 | org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
38 | org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
39 | org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
40 | org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
41 | org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
42 | org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
43 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
44 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
45 | org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
46 | org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
47 | org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
48 | org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
49 | org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
50 | org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
51 | org.eclipse.jdt.core.compiler.problem.nullReference=warning
52 | org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
53 | org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
54 | org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
55 | org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
56 | org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
57 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
58 | org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
59 | org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
60 | org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
61 | org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
62 | org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
63 | org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
64 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
65 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
66 | org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
67 | org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
68 | org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
69 | org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
70 | org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
71 | org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
72 | org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
73 | org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
74 | org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
75 | org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
76 | org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
77 | org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
78 | org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
79 | org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
80 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
81 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
82 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
83 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
84 | org.eclipse.jdt.core.compiler.problem.unusedImport=warning
85 | org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
86 | org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
87 | org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
88 | org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
89 | org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
90 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
91 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
92 | org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
93 | org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
94 | org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
95 | org.eclipse.jdt.core.compiler.source=1.6
96 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.ltk.core.refactoring.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
3 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.m2e.core.prefs:
--------------------------------------------------------------------------------
1 | activeProfiles=
2 | eclipse.preferences.version=1
3 | resolveWorkspaceProjects=true
4 | version=1
5 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | StackSync SyncService is written by:
2 | Cristian Cotes {cristian.cotes [at] urv [dot] cat}
3 | Guillermo Guerrero {guillermo.guerrero [at] urv [dot] cat}
4 | Adrian Moreno {adrian [at] morenomartinez [dot] com}
5 |
6 |
7 | Authors are ordered alphabetically by their surname.
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DISCONTINUED
2 |
3 | StackSync development and maintenance has been discontinued. Thank you to all collaborators that participated in this amazing project.
4 |
5 |
6 | StackSync Synchronization service
7 | =================================
8 |
9 |
10 | **Table of Contents**
11 |
12 | - [Introduction](#introduction)
13 | - [Architecture](#architecture)
14 | - [Synchronization service](#synchronization-service)
15 | - [Requirements](#requirements)
16 | - [Setup](#setup)
17 | - [Database initialization](#database-initialization)
18 | - [Create admin user](#create-admin-user)
19 | - [Create new users](#create-new-users)
20 | - [Compilation](#compilation)
21 | - [Installation](#installation)
22 | - [Issue Tracking](#issue-tracking)
23 | - [Licensing](#licensing)
24 | - [Contact](#contact)
25 |
26 |
27 | # Introduction
28 |
29 | StackSync () is a scalable open source Personal Cloud
30 | that implements the basic components to create a synchronization tool.
31 |
32 |
33 | # Architecture
34 |
35 | In general terms, StackSync can be divided into three main blocks: clients
36 | (desktop and mobile), synchronization service (SyncService) and storage
37 | service (Swift, Amazon S3, FTP...). An overview of the architecture
38 | with the main components and their interaction is shown in the following image.
39 |
40 |
41 |
42 |
43 |
44 | The StackSync client and the SyncService interact through the communication
45 | middleware called ObjectMQ. The sync service interacts with the metadata
46 | database. The StackSync client directly interacts with the storage back-end
47 | to upload and download files.
48 |
49 | As storage back-end we are using OpenStack Swift, an open source cloud storage
50 | software where you can store and retrieve lots of data in virtual containers.
51 | It's based on the Cloud Files offering from Rackspace. But it is also possible
52 | to use other storage back-ends, such as a FTP server or S3.
53 |
54 |
55 | # Synchronization service
56 |
57 | The SyncService is in charge of managing the metadata in order to achieve
58 | data synchronization. Desktop clients communicate with the SyncService for two main
59 | reasons: to obtain the changes occurred when they were offline; and to commit new versions
60 | of a files.
61 |
62 | When a client connects to the system, the first thing it does is asking the SyncService
63 | for changes that were made during the offline time period. This is very common situation
64 | for users working with two different computers, e.g., home and work. Assuming the home
65 | computer is off, if the user modifies some files while at work, the home computer will not
66 | realize about these changes until the user turns on the computer. At this time, the client will
67 | ask the SyncService and update to apply the changes made at work.
68 |
69 | When the server receives a commit operation of a file, it must first check that the meta-
70 | data received is consistent. If the metadata is correct, it proceeds to save it to a database.
71 | Afterwards, a notification is sent to all devices owned by the user reporting the file update.
72 | This provides StackSync with real-time in all devices as they receive notifications of updates
73 | and are always synchronized. However, if the metadata is incorrect, an notification is sent
74 | to the client to fix the error.
75 |
76 |
77 | # Requirements
78 |
79 | * Java 1.6 or newer
80 | * Maven 2
81 | * PostgreSQL 9
82 | * RabbitMQ 3.2.X (Version 3.3.X is not compatible)
83 |
84 | # Setup
85 |
86 | ## Database initialization
87 |
88 | In order to initialize the database we need to create the database and the user and execute the script “setup_db.sql” located in "src/main/resources".
89 |
90 | First, enter in a Postgres command line mode:
91 |
92 | $ sudo -u postgres psql
93 |
94 | Execute the commands below to create a user and the database. The database must be called stacksync:
95 |
96 | postgres=# create database stacksync;
97 | postgres=# create user stacksync_user with password 'mysecretpwd';
98 | postgres=# grant all privileges on database db_name to db_user;
99 | postgres=# \connect db_name
100 | postgres=# CREATE EXTENSION "uuid-ossp";
101 | postgres=# \q
102 |
103 | Enter to the database with the user role created. Note that the first parameter is the host, the second is the database name and the last one is the username:
104 |
105 | $ psql -h localhost db_name db_user
106 |
107 | Now run execute the script.
108 |
109 | postgres=# \i ./setup_db.sql
110 | postgres=# \q
111 |
112 | ## Create admin user
113 |
114 | In order to manage StackSync users in Swift (create containers, set ACLs...) it is necessary to create an admin user in Swift.
115 |
116 | First of all, create a tenant for StackSync:
117 |
118 | $ keystone tenant-create stacksync
119 |
120 | After that, create the admin user under this tenant:
121 |
122 | $ keystone user-create --name stacksync_admin --tenant stacksync --pass "secr3te"
123 |
124 | Finally, assign the admin role to the stacksync_admin user:
125 |
126 | $ keystone user-role-add --user stacksync_admin --role admin --tenant stacksync
127 |
128 | ## Create new users
129 |
130 | Go to the web manager project:
131 | https://github.com/stacksync/manager
132 |
133 |
134 | # Compilation
135 |
136 | We just need to assemble the project into a JAR using Maven:
137 |
138 | $ mvn assembly:assembly
139 |
140 | This will generate a "target" folder containing a JAR file called "syncservice-X.X-jar-with-dependencies.jar"
141 |
142 | > **NOTE**: if you get an error (BUILD FAILURE), cleaning your local Maven repository may fix the problem.
143 |
144 | $ rm -rf ~/.m2/repository/*
145 |
146 | # Create deb package
147 |
148 | Under the folder [packaging/debian](packaging/debian) there is the Makefile to create the deb file.
149 |
150 | $ cd packaging/debian
151 | $ make compile
152 | $ make package
153 |
154 | # Installation
155 | First, install the deb package:
156 |
157 | $ sudo dpkg -i stacksync-server_X.X.X_all.deb
158 |
159 | The StackSync Server has a dependency with the JSVC library, if you experience any problem while installing run the following command:
160 |
161 | $ sudo apt-get -f install
162 |
163 | Once the server is installed, you must modify the configuration file to connect with the database, the messaging middleware, and OpenStack Swift.
164 |
165 | You need to specify a Keystone user capable of creating users and set up ACL on containers on the specific container configured in the file.
166 |
167 | /etc/stacksync-server/stacksync-server.conf
168 |
169 | The init script assumes that you have a "JAVA\_HOME" environment variable set up, if not, it will execute the java located in “/usr/lib/jvm/default-java”. You can change the Java VM by setting up the “JAVA\_HOME” environment or by modifying the script in:
170 |
171 | /etc/init.d/stacksync-server
172 |
173 | Once configured, just run the server.
174 |
175 | $ sudo service stacksync-server start
176 |
177 | If something went wrong, you can check the standard and error log files located in:
178 |
179 | /var/log/stacksync-server/
180 |
181 | # Issue Tracking
182 | We use the GitHub issue tracking.
183 |
184 | # Licensing
185 | StackSync is licensed under the Apache 2.0. Check [LICENSE](LICENSE) for the latest
186 | licensing information.
187 |
188 | # Contact
189 | Visit www.stacksync.com for contact information.
190 |
--------------------------------------------------------------------------------
/config.properties:
--------------------------------------------------------------------------------
1 | # StackSync - SyncService configuration
2 | #
3 | # Type of database used as metadata backend.
4 | # For the moment, only 'postgresql' is available.
5 | datasource=postgresql
6 | #
7 | #
8 | # PostgreSQL configuration
9 | # ========================
10 | #
11 | # Host
12 | postgresql.host=localhost
13 | #
14 | # Port
15 | postgresql.port=5432
16 | #
17 | # Database
18 | postgresql.database=stacksync
19 | #
20 | # User
21 | postgresql.user=stacksync_user
22 | #
23 | # Password
24 | postgresql.password=stacksync
25 | #
26 | #
27 | #
28 | # ObjectMQ configuration
29 | # ======================
30 | # ObjectMQ is the middleware that abstracts the communication between
31 | # the SyncService and the clients. This configuration corresponds with
32 | # the message broker service (AMQP compliant) in charge of handling this
33 | # communication.
34 | #
35 | # Host
36 | omq.host=10.30.233.214
37 | #
38 | # Port
39 | omq.port=5672
40 | #
41 | # User
42 | omq.username=guest
43 | #
44 | # Password
45 | omq.pass=guest
46 | #
47 | # Number of threads
48 | omq.num_threads=4
49 | #
50 | # Exchange queue.
51 | # Must be the same as the one the clients send their requests.
52 | omq.rpc_exchange=rpc_global_exchange
53 | #
54 | #
55 | #
56 | # OpenStack Swift configuration
57 | # =============================
58 | #
59 | # Keystone host
60 | swift.host=10.30.233.214
61 | #
62 | # Keystone host
63 | swift.keystone_host=10.30.233.214
64 | #
65 | # Keystone port
66 | swift.keystone_port=5000
67 | #
68 | # Keystone admin port
69 | swift.keystone_admin_port=35357
70 | #
71 | # Keystone protocol
72 | swift.keystone_protocol=http
73 | #
74 | # Tenant
75 | swift.tenant=stacksync
76 | #
77 | # User
78 | swift.user=stacksync_admin
79 | #
80 | # Password
81 | swift.password=secrete
82 | #
83 |
--------------------------------------------------------------------------------
/packaging/common/stacksync-server:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | /etc/init.d/stacksync-server start
4 |
--------------------------------------------------------------------------------
/packaging/common/stacksync-server.1.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stacksync/sync-service/b9abe53d954fc12fffb101eabbeb9b18acd9951a/packaging/common/stacksync-server.1.gz
--------------------------------------------------------------------------------
/packaging/debian/Makefile:
--------------------------------------------------------------------------------
1 | TARGET_DIR=../../target
2 | JAR_FILE=$(notdir $(wildcard $(TARGET_DIR)/stacksync-server-[0-9.]*-jar-with-dependencies.jar))
3 |
4 | #PACKAGE_NAME=$(shell echo $(JAR_FILE) | sed -e 's/\(-jar-with-dependencies.jar\)//g')
5 | PACKAGE_NAME=stacksync-server
6 | VERSION=$(shell echo $(JAR_FILE) | sed -e 's:stacksync-server-\(.*\)-jar-with-dependencies.jar:\1:g')
7 | CONFIG_DIR=../..
8 | COMMONS_DIR=../common
9 |
10 | all:
11 | @echo 'Please choose a target from the Makefile.'
12 |
13 | .PHONY: clean
14 |
15 | compile:
16 | @cd ../..; mvn clean dependency:copy-dependencies assembly:assembly
17 |
18 | package: clean
19 | # Add changes to changelog
20 | #dch -v $(VERSION)
21 | # Compile source
22 | #cd ../../; mvn clean assembly:assembly
23 | # Create package folder and folder structure
24 | @mkdir -p $(PACKAGE_NAME)/usr/lib/stacksync-server/lib
25 | @mkdir -p $(PACKAGE_NAME)/usr/bin
26 | @mkdir -p $(PACKAGE_NAME)/usr/share/man/man1
27 | @mkdir -p $(PACKAGE_NAME)/var/log/stacksync-server
28 | @mkdir -p $(PACKAGE_NAME)/etc/stacksync-server
29 | @mkdir -p $(PACKAGE_NAME)/etc/init.d
30 | # Copy DEBIAN folder
31 | @cp -r debian $(PACKAGE_NAME)/DEBIAN
32 | # Copy the JAR file
33 | @cp $(TARGET_DIR)/$(JAR_FILE) $(PACKAGE_NAME)/usr/lib/stacksync-server/stacksync-server.jar
34 | # Copy bin script
35 | @cp $(COMMONS_DIR)/stacksync-server $(PACKAGE_NAME)/usr/bin/
36 | # Copy commons-daemon lib
37 | @cp $(TARGET_DIR)/commons-daemon-1.0.15.jar $(PACKAGE_NAME)/usr/lib/stacksync-server/lib/
38 | # Copy man page
39 | @cp $(COMMONS_DIR)/stacksync-server.1.gz $(PACKAGE_NAME)/usr/share/man/man1/
40 | # Copy configuration file
41 | @cp $(CONFIG_DIR)/config.properties $(PACKAGE_NAME)/etc/stacksync-server/stacksync-server.conf
42 | # Move init script
43 | @mv $(PACKAGE_NAME)/DEBIAN/stacksync-server.init $(PACKAGE_NAME)/etc/init.d/stacksync-server
44 | # FIXME: Calculate package size
45 | INSTALLED_SIZE=$(du -sx --exclude DEBIAN $(PACKAGE_NAME) | cut -f1)
46 | # TODO: Update package size
47 | sed -i 's/INSTALLED_SIZE/$(INSTALLED_SIZE)/g' $(PACKAGE_NAME)/DEBIAN/control
48 | # Update version
49 | @sed -i 's/VERSION/$(VERSION)/g' $(PACKAGE_NAME)/DEBIAN/control
50 | # Generate md5sum file
51 | @cd $(PACKAGE_NAME); find . -type f ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -printf '%P ' | xargs md5sum > DEBIAN/md5sums
52 | # Create debian package
53 | @dpkg --build $(PACKAGE_NAME) stacksync-server_$(VERSION)_all.deb
54 |
55 |
56 | clean:
57 | rm -rf $(PACKAGE_NAME)
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/packaging/debian/debian/changelog:
--------------------------------------------------------------------------------
1 | stacksync-server (0.4.4) unstable; urgency=low
2 |
3 | * Initial Release
4 |
5 | -- Adrian Moreno Tue, 03 Dec 2013 16:26:02 +0100
6 |
--------------------------------------------------------------------------------
/packaging/debian/debian/compat:
--------------------------------------------------------------------------------
1 | 7
2 |
--------------------------------------------------------------------------------
/packaging/debian/debian/conffiles:
--------------------------------------------------------------------------------
1 | /etc/stacksync-server/stacksync-server.conf
2 | /etc/init.d/stacksync-server
3 |
--------------------------------------------------------------------------------
/packaging/debian/debian/control:
--------------------------------------------------------------------------------
1 | Package: stacksync-server
2 | Version: VERSION
3 | Section: net
4 | Priority: extra
5 | Installed-Size: 4156
6 | Architecture: all
7 | Depends: jsvc
8 | Homepage: http://www.stacksync.org/
9 | Maintainer: Adrian Moreno
10 | Description: StackSync is an open-source scalable Personal Cloud
11 | StackSync can adapt to the necessities of organizations and
12 | puts a special emphasis on security by encrypting data
13 | on the client side before it is sent to the server.
14 | .
15 | The StackSync Server manages metadata to guarantee a
16 | correct synchronization among all user devices.
17 |
--------------------------------------------------------------------------------
/packaging/debian/debian/dirs:
--------------------------------------------------------------------------------
1 | usr/lib/stacksync-server/lib
2 | usr/bin
3 | usr/share/man/man1
4 | var/log/stacksync-server
5 | etc/stacksync-server
6 |
--------------------------------------------------------------------------------
/packaging/debian/debian/postinst:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # postinst script for stacksync-server
3 |
4 | # create stacksync group
5 | if ! getent group stacksync >/dev/null; then
6 | addgroup --system stacksync
7 | fi
8 |
9 | # create stacksync user
10 | if ! getent passwd stacksync >/dev/null; then
11 | adduser --system --ingroup stacksync --home /usr/lib/stacksync-server \
12 | --no-create-home --gecos "StackSync Server" \
13 | --disabled-login stacksync
14 | fi
15 |
16 |
17 | touch /var/log/stacksync-server/stacksync-server.out
18 | touch /var/log/stacksync-server/stacksync-server.err
19 | chown -R stacksync:stacksync /usr/lib/stacksync-server
20 | chown -R stacksync:stacksync /var/log/stacksync-server
21 | chmod +r /var/log/stacksync-server -R
22 |
23 |
24 | if [ -x "/etc/init.d/stacksync-server" ]; then
25 | if [ ! -e "/etc/stacksync-server/stacksync-server.conf" ]; then
26 | update-rc.d stacksync-server defaults >/dev/null
27 | fi
28 | #invoke-rc.d stacksync-server start || exit $?
29 | fi
30 |
--------------------------------------------------------------------------------
/packaging/debian/debian/postrm:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # postrm script for stacksync-server
3 |
4 | # Automatically added by dh_installinit
5 | #if [ "$1" = "purge" ] ; then
6 | update-rc.d stacksync-server remove >/dev/null
7 | #fi
8 | # End automatically added section
9 |
10 | if [ -d "/var/log/stacksync-server" ]; then
11 | rm -rf /var/log/stacksync-server
12 | fi
13 |
14 | if [ -x "/etc/init.d/stacksync-server" ]; then
15 | rm /etc/init.d/stacksync-server
16 | fi
17 |
--------------------------------------------------------------------------------
/packaging/debian/debian/prerm:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # postinst script for stacksync-server
3 |
4 | # Automatically added by dh_installinit
5 | if [ -x "/etc/init.d/stacksync-server" ]; then
6 | invoke-rc.d stacksync-server stop || exit $?
7 | fi
8 | # End automatically added section
9 |
--------------------------------------------------------------------------------
/packaging/debian/debian/stacksync-server.init:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | # /etc/init.d/stacksync-server
3 |
4 |
5 | if [ `id -u` != `id -u stacksync` -a `id -u` != 0 ] ; then
6 | echo
7 | echo "Only root or stacksync can run stacksync-server"
8 | echo
9 | exit 1
10 | fi
11 |
12 | # If JAVA_HOME environment variable is not set, get the default java VM
13 | if [ -z "$JAVA_HOME" ]; then
14 | JAVA_HOME=/usr/lib/jvm/default-java
15 | fi;
16 |
17 | NAME="stacksync-server"
18 | DESC="StackSync Server"
19 |
20 | # The path to Jsvc
21 | EXEC="/usr/bin/jsvc"
22 |
23 | # The path to the folder containing StackSyncServer.jar
24 | FILE_PATH="/usr/lib/$NAME"
25 |
26 | # Path to configuration folder
27 | CONFIG_PATH="/etc/$NAME"
28 |
29 | # Path to the log folder
30 | LOG_PATH="/var/log/$NAME"
31 |
32 | # Path to std output log
33 | LOG_STD_PATH="$LOG_PATH/stacksync-server.out"
34 |
35 | # Path to error output log
36 | LOG_ERR_PATH="$LOG_PATH/stacksync-server.err"
37 |
38 | # Our classpath including our jar file and the Apache Commons Daemon library
39 | CLASS_PATH="$FILE_PATH/stacksync-server.jar:$FILE_PATH/lib/commons-daemon-1.0.15.jar"
40 |
41 | # The fully qualified name of the class to execute
42 | CLASS="com.stacksync.syncservice.SyncServiceDaemon"
43 |
44 | # Any command line arguments to be passed to the our Java Daemon implementations init() method
45 | ARGS="$CONFIG_PATH/stacksync-server.conf"
46 |
47 | #The user to run the daemon as
48 | USER="stacksync"
49 |
50 | # The file that will contain our process identification number (pid) for other scripts/programs that need to access it.
51 | PID="/var/run/$NAME.pid"
52 |
53 | jsvc_exec()
54 | {
55 | cd $FILE_PATH
56 | $EXEC -outfile $LOG_STD_PATH -errfile $LOG_ERR_PATH -home $JAVA_HOME -cp $CLASS_PATH -user $USER -pidfile $PID -wait 10 $1 $CLASS $ARGS
57 | }
58 |
59 | case "$1" in
60 | start)
61 | echo "Starting $DESC..."
62 |
63 | # Start the service
64 | jsvc_exec
65 |
66 | if [ $? != "0" ]; then
67 | echo "$DESC could not start."
68 | exit 1
69 | fi
70 |
71 | echo "$DESC has started."
72 | ;;
73 | stop)
74 | if [ -f "$PID" ]; then
75 | echo "Stopping $DESC..."
76 |
77 | # Stop the service
78 | jsvc_exec "-stop"
79 |
80 | echo "$DESC has stopped."
81 | else
82 | echo "$DESC not running, no action taken"
83 | fi
84 | ;;
85 | restart)
86 | if [ -f "$PID" ]; then
87 | echo "Restarting the $DESC..."
88 |
89 | # Stop the service
90 | jsvc_exec "-stop"
91 |
92 | # Start the service
93 | jsvc_exec
94 |
95 | echo "The $DESC has restarted."
96 | else
97 | echo "Daemon not running, no action taken"
98 | fi
99 | ;;
100 | status)
101 | if [ -f "$PID" ]; then
102 | echo "$DESC is running."
103 | else
104 | echo "$DESC is NOT running."
105 | fi
106 | ;;
107 | *)
108 | echo "Usage: /etc/init.d/$NAME {start|stop|restart|status}" >&2
109 | exit 3
110 | ;;
111 | esac
112 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | StackSync Server
5 | com.stacksync
6 | stacksync-server
7 | 0.6.13
8 |
9 |
10 | Sonatype repository
11 | Sonatype's Maven repository
12 | http://oss.sonatype.org/content/groups/public
13 |
14 |
15 | Sonatype RSO
16 | Sonatype's Forge repository
17 | https://repository.sonatype.org/content/groups/forge
18 |
19 |
20 | ast-server2
21 | ast-server2-releases
22 | http://ast2-deim.urv.cat/artifactory/ast-internal-repository
23 |
24 |
25 |
26 |
27 | commons-daemon
28 | commons-daemon
29 | 1.0.15
30 |
31 |
32 | com.stacksync
33 | stacksync-commons
34 | 1.4.4
35 |
36 |
37 | objectmq
38 | objectmq
39 | 0.5.7
40 |
41 |
42 | junit
43 | junit
44 | 4.11
45 |
46 |
47 | com.rabbitmq
48 | amqp-client
49 | 3.0.1
50 |
51 |
52 | log4j
53 | log4j
54 | 1.2.16
55 |
56 |
57 | log4j
58 | apache-log4j-extras
59 | 1.1
60 |
61 |
62 | org.apache.xmlrpc
63 | xmlrpc-client
64 | 3.1.2
65 |
66 |
67 | org.apache.xmlrpc
68 | xmlrpc-common
69 | 3.1.2
70 |
71 |
72 | org.apache.xmlrpc
73 | xmlrpc-server
74 | 3.1.2
75 |
76 |
77 | com.google.code.gson
78 | gson
79 | 2.2.4
80 |
81 |
82 | commons-cli
83 | commons-cli
84 | 1.1
85 |
86 |
87 | commons-io
88 | commons-io
89 | 2.2
90 |
91 |
92 | postgresql
93 | postgresql
94 | 9.1-901.jdbc4
95 |
96 |
97 | org.apache.httpcomponents
98 | httpclient
99 | 4.1.2
100 |
101 |
102 | joda-time
103 | joda-time
104 | 2.3
105 |
106 |
107 |
108 |
109 |
110 | src/main/resources
111 | true
112 |
113 | log4j.xml
114 | example.properties
115 | version.properties
116 |
117 |
118 |
119 |
120 |
121 | net.sf.debian-maven
122 | debian-maven-plugin
123 | 1.0.6
124 |
125 |
126 |
127 |
128 | org.apache.maven.plugins
129 | maven-compiler-plugin
130 | 3.1
131 |
132 | 1.6
133 | 1.6
134 |
135 |
136 |
137 | org.apache.maven.plugins
138 | maven-assembly-plugin
139 |
140 |
141 | package
142 |
143 | attached
144 |
145 |
146 |
147 |
148 |
149 | jar-with-dependencies
150 |
151 |
152 |
153 | true
154 | lib/
155 | com.stacksync.syncservice.SyncServiceDaemon
156 |
157 |
158 |
159 |
160 |
161 | org.apache.maven.plugins
162 | maven-dependency-plugin
163 |
164 |
165 | ${project.build.directory}
166 |
167 |
168 |
169 |
170 | org.apache.maven.plugins
171 | maven-surefire-plugin
172 | 2.14.1
173 |
174 | true
175 |
176 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/script/adduser.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ $# != 3 ]; then
4 | echo "USAGE ERROR:"
5 | echo -e "\tsudo $0 "
6 | exit 1
7 | fi
8 |
9 | # Keystone info
10 | IP=IP_HERE
11 | export OS_USERNAME=SWIFT_ADMIN_USER
12 | export OS_PASSWORD=SWIFT_ADMIN_USER_PASS
13 | export OS_TENANT_NAME=SWIFT_ADMIN_TENANT
14 | export OS_AUTH_URL=http://$IP:35357/v2.0
15 |
16 | # StackSync admin user info
17 | STACKSYNC_TENANT=STACKSYNC_TENANT_HERE
18 | STACKSYNC_ADMIN_USER=STACKSYNC_ADMIN_USER_HERE
19 | STACKSYNC_ADMIN_USER_PASS=STACKSYNC_ADMIN_USER_PASS_HERE
20 |
21 | # StackSync database info (postgresql)
22 | STACKSYNC_DB_HOST=localhost
23 | STACKSYNC_DB=STACKSYNC_DB_HERE
24 | STACKSYNC_USER=STACKSYNC_USER_HERE
25 | export PGPASSWORD=STACKSYNC_DB_PASS_HERE
26 |
27 | #Create stacksync user
28 | keystone user-create --name $1 --tenant $STACKSYNC_TENANT --pass $2
29 |
30 | # Login as the StackSync admin and get the token and the storage url
31 | output=$(curl -s -d '{"auth": {"passwordCredentials": {"username": "'$STACKSYNC_ADMIN_USER'", "password": "'$STACKSYNC_ADMIN_USER_PASS'"}, "tenantName":"'$STACKSYNC_TENANT'"}}' -H 'Content-type: application/json' http://$IP:5000/v2.0/tokens)
32 |
33 | ADMINTOKEN=`echo $output | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['access']['token']['id'];"`
34 | STORAGEURL=`echo $output | ruby -e "require 'rubygems'; require 'json'; arrayJson = JSON[STDIN.read]['access']['serviceCatalog'];
35 | arrayJson.each do |object|
36 | if object['name'] == \"swift\"
37 | puts object['endpoints'][0]['publicURL'];
38 | end
39 | end"`
40 |
41 | curl -k -i -X PUT -H "X-Auth-Token: $ADMINTOKEN" -H "X-Container-Read: $STACKSYNC_TENANT:$1" -H "X-Container-Write: $STACKSYNC_TENANT:$1" $STORAGEURL/$1
42 |
43 | # Create DB content
44 | psql -h $STACKSYNC_DB_HOST $STACKSYNC_DB $STACKSYNC_USER -c "INSERT INTO user1 (name, swift_user, swift_account, email, quota_limit, quota_used) VALUES ('$1', '$1', '${STORAGEURL##*/}', '$3', 0, 0);"
45 |
46 | psql -h $STACKSYNC_DB_HOST $STACKSYNC_DB $STACKSYNC_USER -c "INSERT INTO workspace (latest_revision, owner_id, is_shared, swift_container, swift_url) VALUES (0, (SELECT id FROM user1 WHERE name='$1'), false, '$1', '$STORAGEURL');"
47 |
48 | psql -h $STACKSYNC_DB_HOST $STACKSYNC_DB $STACKSYNC_USER -c "INSERT INTO workspace_user(workspace_id, user_id, workspace_name, parent_item_id) VALUES ((SELECT id FROM workspace WHERE swift_container='$1'), (SELECT id FROM user1 WHERE name='$1'), 'default', NULL);"
49 |
--------------------------------------------------------------------------------
/script/install_deps.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | if [[ $UID -ne 0 ]]; then
3 | echo "$0 must be run as root"
4 | exit 1
5 | fi
6 |
7 | ### INSTALL DEPENDENCIES
8 | apt-get -y install ruby python-keystoneclient curl
9 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/SyncServiceDaemon.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.sql.Connection;
7 | import java.sql.SQLException;
8 | import java.util.Properties;
9 |
10 | import omq.common.broker.Broker;
11 |
12 | import org.apache.commons.daemon.Daemon;
13 | import org.apache.commons.daemon.DaemonContext;
14 | import org.apache.commons.daemon.DaemonInitException;
15 | import org.apache.log4j.Logger;
16 |
17 | import com.stacksync.commons.omq.ISyncService;
18 | import com.stacksync.syncservice.db.ConnectionPool;
19 | import com.stacksync.syncservice.db.ConnectionPoolFactory;
20 | import com.stacksync.syncservice.exceptions.dao.DAOConfigurationException;
21 | import com.stacksync.syncservice.omq.SyncServiceImp;
22 | import com.stacksync.syncservice.rpc.XmlRpcSyncHandler;
23 | import com.stacksync.syncservice.rpc.XmlRpcSyncServer;
24 | import com.stacksync.syncservice.storage.StorageFactory;
25 | import com.stacksync.syncservice.storage.StorageManager;
26 | import com.stacksync.syncservice.storage.StorageManager.StorageType;
27 | import com.stacksync.syncservice.util.Config;
28 | import com.stacksync.syncservice.util.Constants;
29 |
30 | public class SyncServiceDaemon implements Daemon {
31 |
32 | private static final Logger logger = Logger
33 | .getLogger(SyncServiceDaemon.class.getName());
34 | private static ConnectionPool pool = null;
35 | private static XmlRpcSyncServer xmlRpcServer = null;
36 | private static Broker broker = null;
37 | private static SyncServiceImp syncService = null;
38 |
39 | @Override
40 | public void init(DaemonContext dc) throws DaemonInitException, Exception {
41 |
42 | logger.info(String.format("Initializing StackSync Server v%s...",
43 | SyncServiceDaemon.getVersion()));
44 |
45 | logger.info(String.format("Java VM: %s", System.getProperty("java.vm.name")));
46 | logger.info(String.format("Java VM version: %s", System.getProperty("java.vm.version")));
47 | logger.info(String.format("Java Home: %s", System.getProperty("java.home")));
48 | logger.info(String.format("Java version: %s", System.getProperty("java.version")));
49 |
50 | try {
51 | String[] argv = dc.getArguments();
52 |
53 | if (argv.length == 0) {
54 | logger.error("No config file passed to StackSync Server.");
55 | System.exit(1);
56 | }
57 |
58 | String configPath = argv[0];
59 |
60 | File file = new File(configPath);
61 | if (!file.exists()) {
62 | logger.error("'" + configPath + "' file not found");
63 | System.exit(2);
64 | }
65 |
66 | Config.loadProperties(configPath);
67 |
68 | } catch (IOException e) {
69 | logger.error("Could not load properties file.", e);
70 | System.exit(7);
71 | }
72 |
73 | try {
74 |
75 | String datasource = Config.getDatasource();
76 | pool = ConnectionPoolFactory.getConnectionPool(datasource);
77 |
78 | // it will try to connect to the DB, throws exception if not
79 | // possible.
80 | Connection conn = pool.getConnection();
81 | conn.close();
82 |
83 | logger.info("Connection to database succeded");
84 | } catch (DAOConfigurationException e) {
85 | logger.error("Connection to database failed.", e);
86 | System.exit(3);
87 | } catch (SQLException e) {
88 | logger.error("Connection to database failed.", e);
89 | System.exit(4);
90 | }
91 |
92 | logger.info("Connecting to OpenStack Swift...");
93 |
94 | try {
95 | StorageType type;
96 | if (Config.getSwiftKeystoneProtocol().equals("http")) {
97 | type = StorageType.SWIFT;
98 | } else {
99 | type = StorageType.SWIFT_SSL;
100 | }
101 | StorageManager storageManager = StorageFactory.getStorageManager(type);
102 | storageManager.login();
103 | logger.info("Connected to OpenStack Swift successfully");
104 | } catch (Exception e) {
105 | logger.fatal("Could not connect to Swift.", e);
106 | System.exit(7);
107 | }
108 |
109 |
110 | logger.info("Initializing the messaging middleware...");
111 | try {
112 | broker = new Broker(Config.getProperties());
113 | syncService = new SyncServiceImp(broker, pool);
114 | logger.info("Messaging middleware initialization succeeded");
115 | } catch (Exception e) {
116 | logger.error("Could not initialize ObjectMQ.", e);
117 | System.exit(5);
118 | }
119 | }
120 |
121 | @Override
122 | public void start() throws Exception {
123 |
124 | try {
125 | broker.bind(ISyncService.class.getSimpleName(), syncService);
126 | logger.info("StackSync Server is ready and waiting for messages...");
127 | } catch (Exception e) {
128 | logger.fatal("Could not bind queue.", e);
129 | System.exit(5);
130 | }
131 |
132 | logger.info("Initializing XML RPC...");
133 | try {
134 | launchXmlRpc();
135 | logger.info("XML RPC initialization succeded");
136 | } catch (Exception e) {
137 | logger.fatal("Could not initialize XMLRPC.", e);
138 | System.exit(6);
139 | }
140 | }
141 |
142 | @Override
143 | public void stop() throws Exception {
144 | try {
145 | broker.stopBroker();
146 | } catch (Exception e) {
147 | logger.fatal("Error stoping StackSync Server.", e);
148 | throw e;
149 | }
150 | }
151 |
152 | @Override
153 | public void destroy() {
154 | broker = null;
155 | }
156 |
157 | private static void launchXmlRpc() throws Exception {
158 | xmlRpcServer = new XmlRpcSyncServer(Constants.XMLRPC_PORT);
159 | xmlRpcServer.addHandler("XmlRpcSyncHandler", new XmlRpcSyncHandler(
160 | broker, pool));
161 | xmlRpcServer.serve_forever();
162 | }
163 |
164 | private static String getVersion() {
165 | String path = "/version.properties";
166 | InputStream stream = Config.class.getResourceAsStream(path);
167 | if (stream == null) {
168 | return "UNKNOWN";
169 | }
170 | Properties props = new Properties();
171 | try {
172 | props.load(stream);
173 | stream.close();
174 | return (String) props.get("version");
175 | } catch (IOException e) {
176 | return "UNKNOWN";
177 | }
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/ConnectionPool.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db;
2 |
3 | import java.sql.Connection;
4 | import java.sql.SQLException;
5 |
6 | public abstract class ConnectionPool {
7 |
8 | public abstract Connection getConnection() throws SQLException;
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/ConnectionPoolFactory.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db;
2 |
3 | import org.apache.log4j.Logger;
4 |
5 | import com.stacksync.syncservice.db.postgresql.PostgresqlConnectionPool;
6 | import com.stacksync.syncservice.exceptions.dao.DAOConfigurationException;
7 | import com.stacksync.syncservice.util.Config;
8 |
9 | public class ConnectionPoolFactory {
10 | private static final Logger logger = Logger.getLogger(ConnectionPoolFactory.class.getName());
11 |
12 | public static ConnectionPool getConnectionPool(String datasource) throws DAOConfigurationException {
13 |
14 | if ("postgresql".equalsIgnoreCase(datasource)) {
15 | // Obtain info
16 | String host = Config.getPostgresqlHost();
17 | Integer port = Config.getPostgresqlPort();
18 | String database = Config.getPostgresqlDatabase();
19 | String password = Config.getPostgresqlPassword();
20 | String username = Config.getPostgresqlUsername();
21 | int initialConns = Config.getPostgresqlInitialConns();
22 | int maxConns = Config.getPostgresqlMaxConns();
23 |
24 | //
25 | return new PostgresqlConnectionPool(host, port, database, username, password, initialConns, maxConns);
26 | }
27 |
28 | logger.error("Could not find any driver matching your request");
29 | throw new DAOConfigurationException("Driver not found");
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/DAOError.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db;
2 |
3 | public enum DAOError {
4 |
5 | // These errors codes correspond to HTTP codes
6 | // Users
7 | USER_NOT_FOUND(400, "User not found."), USER_NOT_AUTHORIZED(401,
8 | "The user is not authorized to access to this resource."),
9 |
10 | // Workspaces
11 | WORKSPACES_NOT_FOUND(410, "Workspaces not found."),
12 |
13 | // Files
14 | FILE_NOT_FOUND(404, "File or folder not found."),
15 |
16 | // Server
17 | INTERNAL_SERVER_ERROR(500, "Internal Server Error");
18 |
19 | private final int code;
20 | private final String message;
21 |
22 | DAOError(int code, String message) {
23 | this.code = code;
24 | this.message = message;
25 | }
26 |
27 | public int getCode() {
28 | return code;
29 | }
30 |
31 | public String getMessage() {
32 | return message;
33 | }
34 | }
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/DAOFactory.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db;
2 |
3 | import java.sql.Connection;
4 |
5 | import com.stacksync.syncservice.db.postgresql.PostgresqlDeviceDAO;
6 | import com.stacksync.syncservice.db.postgresql.PostgresqlItemDAO;
7 | import com.stacksync.syncservice.db.postgresql.PostgresqlItemVersionDao;
8 | import com.stacksync.syncservice.db.postgresql.PostgresqlUserDAO;
9 | import com.stacksync.syncservice.db.postgresql.PostgresqlWorkspaceDAO;
10 |
11 | public class DAOFactory {
12 |
13 | private String type;
14 |
15 | public DAOFactory(String type) {
16 | this.type = type;
17 | }
18 |
19 | public WorkspaceDAO getWorkspaceDao(Connection connection) {
20 | return new PostgresqlWorkspaceDAO(connection);
21 | }
22 |
23 | public UserDAO getUserDao(Connection connection) {
24 | return new PostgresqlUserDAO(connection);
25 | }
26 |
27 | public ItemDAO getItemDAO(Connection connection) {
28 | return new PostgresqlItemDAO(connection);
29 | }
30 |
31 | public ItemVersionDAO getItemVersionDAO(Connection connection) {
32 | return new PostgresqlItemVersionDao(connection);
33 | }
34 |
35 | public DeviceDAO getDeviceDAO(Connection connection) {
36 | return new PostgresqlDeviceDAO(connection);
37 | }
38 |
39 | public String getType() {
40 | return type;
41 | }
42 |
43 | public void setType(String type) {
44 | this.type = type;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/DeviceDAO.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db;
2 |
3 | import java.util.UUID;
4 |
5 | import com.stacksync.commons.models.Device;
6 | import com.stacksync.syncservice.exceptions.dao.DAOException;
7 |
8 | public interface DeviceDAO {
9 |
10 | public Device get(UUID id) throws DAOException;
11 |
12 | public void add(Device device) throws DAOException;
13 |
14 | public void update(Device device) throws DAOException;
15 |
16 | public void delete(UUID id) throws DAOException;
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/ItemDAO.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db;
2 |
3 | import java.util.List;
4 | import java.util.UUID;
5 |
6 | import com.stacksync.commons.models.Item;
7 | import com.stacksync.commons.models.ItemMetadata;
8 | import com.stacksync.syncservice.exceptions.dao.DAOException;
9 |
10 | public interface ItemDAO {
11 | public Item findById(Long id) throws DAOException;
12 |
13 | public void add(Item item) throws DAOException;
14 |
15 | public void update(Item item) throws DAOException;
16 |
17 | public void put(Item item) throws DAOException;
18 |
19 | public void delete(Long id) throws DAOException;
20 |
21 | // ItemMetadata information
22 | public List getItemsByWorkspaceId(UUID workspaceId) throws DAOException;
23 |
24 | public List getItemsById(Long id) throws DAOException;
25 |
26 | public ItemMetadata findById(Long id, Boolean includeList, Long version, Boolean includeDeleted, Boolean includeChunks) throws DAOException;
27 |
28 | public ItemMetadata findByUserId(UUID serverUserId, Boolean includeDeleted) throws DAOException;
29 |
30 | public ItemMetadata findItemVersionsById(Long id) throws DAOException;
31 |
32 | public List migrateItem(Long itemId, UUID workspaceId) throws DAOException;
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/ItemVersionDAO.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db;
2 |
3 | import java.util.List;
4 |
5 | import com.stacksync.commons.models.Chunk;
6 | import com.stacksync.commons.models.ItemMetadata;
7 | import com.stacksync.commons.models.ItemVersion;
8 | import com.stacksync.syncservice.exceptions.dao.DAOException;
9 |
10 | public interface ItemVersionDAO {
11 |
12 | public ItemMetadata findByItemIdAndVersion(Long id, Long version) throws DAOException;;
13 |
14 | public void add(ItemVersion itemVersion) throws DAOException;
15 |
16 | public void insertChunk(Long itemVersionId, Long chunkId, Integer order) throws DAOException;
17 |
18 | public void insertChunks(List chunks, long itemVersionId) throws DAOException;
19 |
20 | public List findChunks(Long itemVersionId) throws DAOException;
21 |
22 | public void update(ItemVersion itemVersion) throws DAOException;
23 |
24 | public void delete(ItemVersion itemVersion) throws DAOException;
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/UserDAO.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db;
2 |
3 | import java.util.List;
4 | import java.util.UUID;
5 |
6 | import com.stacksync.commons.models.User;
7 | import com.stacksync.syncservice.exceptions.dao.DAOException;
8 |
9 | public interface UserDAO {
10 |
11 | public User findById(UUID id) throws DAOException;
12 |
13 | public User getByEmail(String email) throws DAOException;
14 |
15 | public List findAll() throws DAOException;
16 |
17 | public List findByItemId(Long clientFileId) throws DAOException;
18 |
19 | public void add(User user) throws DAOException;
20 |
21 | public void update(User user) throws DAOException;
22 |
23 | public void delete(UUID id) throws DAOException;
24 |
25 | public void updateAvailableQuota(User user) throws DAOException;
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/WorkspaceDAO.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db;
2 |
3 | import java.util.List;
4 | import java.util.UUID;
5 |
6 | import com.stacksync.commons.models.User;
7 | import com.stacksync.commons.models.UserWorkspace;
8 | import com.stacksync.commons.models.Workspace;
9 | import com.stacksync.syncservice.exceptions.dao.DAOException;
10 |
11 | public interface WorkspaceDAO {
12 |
13 | public Workspace getById(UUID id) throws DAOException;
14 |
15 | public List getByUserId(UUID userId) throws DAOException;
16 |
17 | public Workspace getDefaultWorkspaceByUserId(UUID userId) throws DAOException;
18 |
19 | public Workspace getByItemId(Long itemId) throws DAOException;
20 |
21 | public void add(Workspace workspace) throws DAOException;
22 |
23 | public void update(User user, Workspace workspace) throws DAOException;
24 |
25 | public void addUser(User user, Workspace workspace) throws DAOException;
26 |
27 | public void deleteUser(User user, Workspace workspace) throws DAOException;
28 |
29 | public void delete(UUID id) throws DAOException;
30 |
31 | public List getMembersById(UUID workspaceId) throws DAOException;
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/postgresql/PostgresqlConnectionPool.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db.postgresql;
2 |
3 | import java.sql.Connection;
4 | import java.sql.SQLException;
5 |
6 | import org.postgresql.ds.PGPoolingDataSource;
7 |
8 | import com.stacksync.syncservice.db.ConnectionPool;
9 | import com.stacksync.syncservice.exceptions.dao.DAOConfigurationException;
10 |
11 | public class PostgresqlConnectionPool extends ConnectionPool {
12 |
13 | private PGPoolingDataSource source;
14 |
15 | public PostgresqlConnectionPool(String host, int port, String database, String username, String password, int initialConns, int maxConns)
16 | throws DAOConfigurationException {
17 | try {
18 | Class.forName("org.postgresql.Driver");
19 |
20 | // Initialize a pooling DataSource
21 | source = new PGPoolingDataSource();
22 | source.setDatabaseName(database);
23 | source.setServerName(host);
24 | source.setPortNumber(port);
25 | source.setUser(username);
26 | source.setPassword(password);
27 | source.setInitialConnections(initialConns);
28 | source.setMaxConnections(maxConns);
29 | source.getConnection().close();
30 |
31 | } catch (ClassNotFoundException e) {
32 | throw new DAOConfigurationException("PostgreSQL JDBC driver not found", e);
33 | } catch (SQLException e) {
34 | throw new DAOConfigurationException("SQLException catched at DAOFactory", e);
35 | }
36 |
37 | }
38 |
39 | @Override
40 | public synchronized Connection getConnection() throws SQLException {
41 | try {
42 | return source.getConnection();
43 | } catch (Exception e) {
44 | throw new SQLException(e);
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/postgresql/PostgresqlDAO.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db.postgresql;
2 |
3 | import static com.stacksync.syncservice.db.DAOUtil.prepareStatement;
4 |
5 | import java.sql.Connection;
6 | import java.sql.PreparedStatement;
7 | import java.sql.ResultSet;
8 | import java.sql.SQLException;
9 |
10 | import org.apache.log4j.Logger;
11 |
12 | import com.stacksync.syncservice.db.DAOError;
13 | import com.stacksync.syncservice.exceptions.dao.DAOException;
14 | import com.stacksync.syncservice.exceptions.dao.NoRowsAffectedDAOException;
15 |
16 | public class PostgresqlDAO {
17 | private static final Logger logger = Logger.getLogger(PostgresqlDAO.class.getName());
18 | protected Connection connection;
19 |
20 | public PostgresqlDAO(Connection connection) {
21 | this.connection = connection;
22 | }
23 |
24 | protected ResultSet executeQuery(String query, Object[] values) throws DAOException {
25 |
26 | PreparedStatement preparedStatement = null;
27 | ResultSet resultSet = null;
28 |
29 | try {
30 | preparedStatement = prepareStatement(connection, query, false, values);
31 | resultSet = preparedStatement.executeQuery();
32 |
33 | } catch (SQLException e) {
34 | logger.error(e);
35 | throw new DAOException(e, DAOError.INTERNAL_SERVER_ERROR);
36 | }
37 |
38 | return resultSet;
39 | }
40 |
41 | protected Object executeUpdate(String query, Object[] values) throws DAOException {
42 |
43 | Object key = null;
44 | PreparedStatement preparedStatement = null;
45 | ResultSet generatedKeys = null;
46 |
47 | try {
48 | preparedStatement = prepareStatement(connection, query, true, values);
49 | int affectedRows = preparedStatement.executeUpdate();
50 | if (affectedRows == 0) {
51 | throw new NoRowsAffectedDAOException("Execute update error: no rows affected.");
52 | }
53 |
54 | if (query.startsWith("INSERT")) {
55 | generatedKeys = preparedStatement.getGeneratedKeys();
56 |
57 | if (generatedKeys.next()) {
58 | key = generatedKeys.getObject(1);
59 | } else {
60 | throw new DAOException("Creating object failed, no generated key obtained.");
61 | }
62 | }
63 |
64 | } catch (SQLException e) {
65 | logger.error(e);
66 | throw new DAOException(e, DAOError.INTERNAL_SERVER_ERROR);
67 | }
68 |
69 | return key;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/postgresql/PostgresqlDeviceDAO.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db.postgresql;
2 |
3 | import java.sql.Connection;
4 | import java.sql.ResultSet;
5 | import java.sql.SQLException;
6 | import java.util.UUID;
7 |
8 | import org.apache.log4j.Logger;
9 |
10 | import com.stacksync.commons.models.Device;
11 | import com.stacksync.commons.models.User;
12 | import com.stacksync.syncservice.db.DeviceDAO;
13 | import com.stacksync.syncservice.exceptions.dao.DAOException;
14 | import com.stacksync.syncservice.util.Constants;
15 |
16 | public class PostgresqlDeviceDAO extends PostgresqlDAO implements DeviceDAO {
17 |
18 | private static final Logger logger = Logger.getLogger(PostgresqlDeviceDAO.class.getName());
19 |
20 | public PostgresqlDeviceDAO(Connection connection) {
21 | super(connection);
22 | }
23 |
24 | @Override
25 | public Device get(UUID deviceID) throws DAOException {
26 |
27 | // API device ID is not stored in the database
28 | if(deviceID == Constants.API_DEVICE_ID){
29 | return new Device(Constants.API_DEVICE_ID);
30 | }
31 |
32 | ResultSet resultSet = null;
33 | Device device = null;
34 |
35 | String query = "SELECT * FROM device WHERE id = ?::uuid";
36 |
37 | try {
38 | resultSet = executeQuery(query, new Object[] { deviceID });
39 |
40 | if (resultSet.next()) {
41 | device = mapDevice(resultSet);
42 | }
43 | } catch (SQLException e) {
44 | throw new DAOException(e);
45 | }
46 |
47 | return device;
48 | }
49 |
50 | @Override
51 | public void add(Device device) throws DAOException {
52 | if (!device.isValid()) {
53 | throw new IllegalArgumentException("Device attributes not set");
54 | }
55 |
56 | Object[] values = { device.getName(), device.getUser().getId(), device.getOs(),
57 | device.getLastIp(), device.getAppVersion() };
58 |
59 | String query = "INSERT INTO device (name, user_id, os, created_at, last_access_at, last_ip, app_version) "
60 | + "VALUES (?, ?::uuid, ?, now(), now(), ?::inet, ?)";
61 |
62 | UUID id = (UUID) executeUpdate(query, values);
63 |
64 | if (id != null) {
65 | device.setId(id);
66 | }
67 | }
68 |
69 | @Override
70 | public void update(Device device) throws DAOException {
71 | if (device.getId() == null || !device.isValid()) {
72 | throw new IllegalArgumentException("Device attributes not set");
73 | }
74 |
75 | Object[] values = { device.getLastIp(), device.getAppVersion(), device.getId(), device.getUser().getId() };
76 |
77 | String query = "UPDATE device SET last_access_at = now(), last_ip = ?::inet, app_version = ? "
78 | + "WHERE id = ?::uuid and user_id = ?::uuid";
79 |
80 | try {
81 | executeUpdate(query, values);
82 | } catch (DAOException e) {
83 | logger.error(e);
84 | throw new DAOException(e);
85 | }
86 | }
87 |
88 | @Override
89 | public void delete(UUID deviceID) throws DAOException {
90 | Object[] values = { deviceID };
91 |
92 | String query = "DELETE FROM device WHERE id = ?::uuid";
93 |
94 | executeUpdate(query, values);
95 | }
96 |
97 | private Device mapDevice(ResultSet resultSet) throws SQLException {
98 |
99 | Device device = new Device();
100 | device.setId(UUID.fromString(resultSet.getString("id")));
101 | device.setName(resultSet.getString("name"));
102 |
103 | User user = new User();
104 | user.setId(UUID.fromString(resultSet.getString("user_id")));
105 |
106 | device.setUser(user);
107 |
108 | return device;
109 |
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/com/stacksync/syncservice/db/postgresql/PostgresqlItemVersionDao.java:
--------------------------------------------------------------------------------
1 | package com.stacksync.syncservice.db.postgresql;
2 |
3 | import java.sql.Connection;
4 | import java.sql.ResultSet;
5 | import java.sql.SQLException;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import org.apache.log4j.Logger;
10 |
11 | import com.stacksync.commons.models.Chunk;
12 | import com.stacksync.commons.models.ItemMetadata;
13 | import com.stacksync.commons.models.ItemVersion;
14 | import com.stacksync.syncservice.db.DAOError;
15 | import com.stacksync.syncservice.db.DAOUtil;
16 | import com.stacksync.syncservice.db.ItemVersionDAO;
17 | import com.stacksync.syncservice.exceptions.dao.DAOException;
18 |
19 | public class PostgresqlItemVersionDao extends PostgresqlDAO implements ItemVersionDAO {
20 |
21 | private static final Logger logger = Logger.getLogger(PostgresqlItemVersionDao.class.getName());
22 |
23 | public PostgresqlItemVersionDao(Connection connection) {
24 | super(connection);
25 | }
26 |
27 | @Override
28 | public ItemMetadata findByItemIdAndVersion(Long id, Long version) throws DAOException {
29 | Object[] values = { id, version };
30 |
31 | String query = "SELECT i.id AS item_id, i.parent_id, i.client_parent_file_version, i.filename, i.is_folder, i.mimetype, i.workspace_id, "
32 | + " iv.version, iv.device_id, iv.checksum, iv.status, iv.size, iv.modified_at, "
33 | + " get_chunks(iv.id) AS chunks "
34 | + " FROM item_version iv "
35 | + " INNER JOIN item i ON i.id = iv.item_id "
36 | + " WHERE iv.item_id = ? and iv.version = ?";
37 |
38 | ResultSet result = null;
39 | ItemMetadata metadata = null;
40 |
41 | try {
42 |
43 | result = executeQuery(query, values);
44 |
45 | if (result.next()) {
46 |
47 | metadata = DAOUtil.getItemMetadataFromResultSet(result);
48 | } else {
49 | // TODO error, no ha encontrado nada el perroo
50 | // throw workspace not found??
51 | }
52 |
53 | } catch (SQLException e) {
54 | logger.error(e);
55 | throw new DAOException(DAOError.INTERNAL_SERVER_ERROR);
56 | }
57 |
58 | return metadata;
59 | }
60 |
61 | @Override
62 | public void add(ItemVersion itemVersion) throws DAOException {
63 | if (!itemVersion.isValid()) {
64 | throw new IllegalArgumentException("Item version attributes not set");
65 | }
66 |
67 | Object[] values = { itemVersion.getItem().getId(), itemVersion.getDevice().getId(), itemVersion.getVersion(),
68 | itemVersion.getChecksum(), itemVersion.getStatus(), itemVersion.getSize(),
69 | new java.sql.Timestamp(itemVersion.getModifiedAt().getTime()) };
70 |
71 | String query = "INSERT INTO item_version( item_id, device_id, version, "
72 | + "checksum, status, size, modified_at, committed_at ) " + "VALUES ( ?, ?, ?, ?, ?, ?, ?, now() )";
73 |
74 | Long id = (Long)executeUpdate(query, values);
75 |
76 | if (id != null) {
77 | itemVersion.setId(id);
78 | }
79 |
80 | }
81 |
82 | @Override
83 | public void update(ItemVersion itemVersion) throws DAOException {
84 | // TODO Auto-generated method stub
85 |
86 | }
87 |
88 | @Override
89 | public void delete(ItemVersion itemVersion) throws DAOException {
90 | // TODO Auto-generated method stub
91 |
92 | }
93 |
94 | @Override
95 | public void insertChunk(Long itemVersionId, Long chunkId, Integer order) throws DAOException {
96 | Object[] values = { itemVersionId, chunkId, order };
97 |
98 | String query = "INSERT INTO item_version_chunk( item_version_id, chunk_id, chunk_order ) "
99 | + "VALUES ( ?, ?, ? )";
100 |
101 | try {
102 | executeUpdate(query, values);
103 | } catch (DAOException e) {
104 | logger.error(e);
105 | throw new DAOException(DAOError.INTERNAL_SERVER_ERROR);
106 | }
107 | }
108 |
109 | @Override
110 | public void insertChunks(List chunks, long itemVersionId) throws DAOException {
111 | if (chunks.isEmpty()) {
112 | throw new IllegalArgumentException("No chunks received");
113 | }
114 |
115 | List