bugs and clean up and retry when db connection failed

pull/14/head
leonnicolas 4 years ago
parent 0098d9b3bf
commit 2e02920d75
No known key found for this signature in database
GPG Key ID: 088D0743E2B65C07

@ -11,7 +11,6 @@ Userserver and postgres are running e.g. with Julius' Docker Compose.
docker build -t <image name> .
docker run --rm -p 4000:4000 <image name>
```
The Dockerfile is pretty stupid and could produce a smaller image, e.g. with multistage build.
### Compile and run
Install gulp if not installed
```bash
@ -23,7 +22,7 @@ gulp
npm start
```
### For Development
Install node_modules and gulp
Install node\_modules and gulp
```bash
npm -g gulp
npm install

@ -13,14 +13,6 @@ export class ContactInformationAPI extends DataSource {
this.connection = getConnection();
}
async numContactInformationById (id: number) {
return await this.connection.getRepository(ContactInformation)
.createQueryBuilder('contactInformation')
.select()
.where('"contactInformation".id = :id', { id: id })
.getCount();
}
async contactInformation (offset: number, limit: number) {
return await this.connection.getRepository(ContactInformation)
.createQueryBuilder('ci')

@ -146,6 +146,14 @@ export class ParticipantAPI extends DataSource {
.loadOne();
}
async workshopsByParticipantId (id: number) {
return await this.connection.getRepository(Participant)
.createQueryBuilder('p')
.relation(Participant, 'workshopIds')
.of(id)
.loadMany();
}
/**
* creates participant and creates relation to given contactInformation
* @param participant to be created
@ -160,6 +168,11 @@ export class ParticipantAPI extends DataSource {
.values([participant])
.returning('*')
.execute();
await entityManager.getRepository(Participant)
.createQueryBuilder('w')
.relation(Participant, 'workshopIds')
.of(participant.id)
.add(participant.workshopIds);
});
return this.participantById(inserts?.identifiers[0].id);
}
@ -179,6 +192,8 @@ export class ParticipantAPI extends DataSource {
if (await LockUtils.isLocked(entityManager, Participant, 'p', participant.id, userId)) {
throw new GraphQLError('Participant is locked by another user');
}
const workshops = participant.workshopIds;
delete participant.workshopIds;
await ActionLogger.log(entityManager, Participant, 'p', participant, userId);
await entityManager.getRepository(Participant)
.createQueryBuilder('p')
@ -186,6 +201,11 @@ export class ParticipantAPI extends DataSource {
.set({ ...participant })
.where('id = :id', { id: participant.id })
.execute().then(value => { if (value.affected !== 1) { throw new GraphQLError('ID not found'); } });
await entityManager.getRepository(Participant)
.createQueryBuilder('w')
.relation(Participant, 'workshopIds')
.of(participant.id)
.add(workshops);
});
!keepLock && await this.unlockParticipant(participant.id, userId);
return await this.participantById(participant.id);

@ -5,6 +5,7 @@ import { Workshop } from '../../model/Workshop';
import { ActionLogger, deleteEntity, LockUtils } from './utils';
import { UserInputError } from 'apollo-server-express';
import { GraphQLError } from 'graphql';
import { Participant } from '../../model/Participant';
export class WorkshopAPI extends DataSource {
connection: Connection
@ -152,4 +153,12 @@ export class WorkshopAPI extends DataSource {
.of(id)
.loadOne();
}
async participantsByWorkshopId (id: number): Promise<Participant[]> {
return await this.connection.getRepository(Workshop)
.createQueryBuilder('w')
.relation(Workshop, 'participantIds')
.of(id)
.loadMany();
}
}

@ -1,9 +1,9 @@
import { ApolloServer } from 'apollo-server-express';
import bikeresolver from './resolvers/cargobikeResolver';
import bikeResolver from './resolvers/cargoBikeResolver';
import { CargoBikeAPI } from './datasources/db/cargobikeAPI';
import typeDefs from './schema/type-defs';
import 'reflect-metadata';
import { createConnection } from 'typeorm';
import { ConnectionOptions, createConnection } from 'typeorm';
import { UserServerAPI } from './datasources/userserver/userserviceAPI';
import express from 'express';
import { requiredPermissions } from './datasources/userserver/permission';
@ -19,13 +19,13 @@ import { Provider } from './model/Provider';
import { Engagement } from './model/Engagement';
import { Workshop } from './model/Workshop';
import { LendingStationAPI } from './datasources/db/lendingstationAPI';
import lendingstationResolvers from './resolvers/lendingstationResolvers';
import lendingStationResolvers from './resolvers/lendingStationResolvers';
import { ParticipantAPI } from './datasources/db/participantAPI';
import participantResolvers from './resolvers/participantResolvers';
import { ContactInformationAPI } from './datasources/db/contactinformationAPI';
import providerResolvers from './resolvers/providerResolvers';
import { ProviderAPI } from './datasources/db/providerAPI';
import contactinformationResolvers from './resolvers/contactinformationResolvers';
import contactInformationResolvers from './resolvers/contactInformationResolvers';
import { Person } from './model/Person';
import { WorkshopType } from './model/WorkshopType';
import { EngagementType } from './model/EngagementType';
@ -34,11 +34,36 @@ import { BikeEventType } from './model/BikeEventType';
import { WorkshopAPI } from './datasources/db/workshopAPI';
import workshopResolvers from './resolvers/workshopResolvers';
import { ActionLog } from './model/ActionLog';
import actionlogResolvers from './resolvers/actionlogResolvers';
import actionLogResolvers from './resolvers/actionLogResolvers';
import { ActionLogAPI } from './datasources/db/actionLogAPI';
require('dotenv').config();
const connOptions: ConnectionOptions = {
type: 'postgres',
url: process.env.POSTGRES_CONNECTION_URL,
entities: [
CargoBike,
BikeEvent,
BikeEventType,
ContactInformation,
Equipment,
EquipmentType,
LendingStation,
TimeFrame,
Organisation,
Participant,
Provider,
Engagement,
EngagementType,
Workshop,
Person,
WorkshopType,
ActionLog
],
synchronize: true,
logging: false
};
/**
* Function that is called to authenticate a user by using the user rpc server
* @param req
@ -68,45 +93,26 @@ async function authenticate (req: any, res: any, next: any) {
}
}
createConnection({
type: 'postgres',
url: process.env.POSTGRES_CONNECTION_URL,
entities: [
CargoBike,
BikeEvent,
BikeEventType,
ContactInformation,
Equipment,
EquipmentType,
LendingStation,
TimeFrame,
Organisation,
Participant,
Provider,
Engagement,
EngagementType,
Workshop,
Person,
WorkshopType,
ActionLog
],
synchronize: true,
logging: false
}).then(async () => {
console.log('connected to db');
}).catch(error => console.log(error));
function retryConnect (): any {
createConnection(connOptions).catch(error => {
console.log(error);
setTimeout(retryConnect, 3000);
});
}
retryConnect();
const userAPI = new UserServerAPI(process.env.RPC_HOST);
const server = new ApolloServer({
resolvers: [
bikeresolver,
lendingstationResolvers,
bikeResolver,
lendingStationResolvers,
participantResolvers,
providerResolvers,
contactinformationResolvers,
contactInformationResolvers,
workshopResolvers,
actionlogResolvers
actionLogResolvers
],
typeDefs,
dataSources: () => ({
@ -130,8 +136,7 @@ app.post('/graphql', authenticate);
app.get(/\/graphql?&.*query=/, authenticate);
server.applyMiddleware({ app });
console.log(__dirname);
app.listen(4000, async () => {
console.log('Server listening on port 4000');
await userAPI.createDefinedPermissions();
await userAPI.createDefinedPermissions().catch(
err => console.log(err));
});

@ -1,4 +1,4 @@
import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn, OneToMany, ManyToMany } from 'typeorm';
import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn, OneToMany, ManyToMany, JoinTable } from 'typeorm';
import { ContactInformation } from './ContactInformation';
import { Engagement } from './Engagement';
import { Workshop } from './Workshop';
@ -47,10 +47,11 @@ export class Participant implements Lockable {
@OneToMany(type => Engagement, engagement => engagement.participantId)
engagement: Engagement[];
@ManyToMany(type => Workshop, workshop => workshop.participants, {
@ManyToMany(type => Workshop, workshop => workshop.participantIds, {
nullable: true
})
workshops: Workshop[];
@JoinTable()
workshopIds: number[];
@Column({
nullable: false,

@ -22,10 +22,10 @@ export class Workshop implements Lockable {
})
date: Date;
@ManyToMany(type => Participant, participant => participant.workshops, {
@ManyToMany(type => Participant, participant => participant.workshopIds, {
nullable: true
})
participants: Participant[];
participantIds: number[];
@ManyToOne(type => Participant, {
nullable: false

@ -62,6 +62,13 @@ export default {
return new GraphQLError('Insufficient Permissions');
}
},
workshops (parent: any, _: any, { dataSources, req }: { dataSources: any, req: any }) {
if (req.permissions.includes(Permission.ReadWorkshop)) {
return (dataSources.participantAPI.workshopsByParticipantId(parent.id));
} else {
return new GraphQLError('Insufficient Permissions');
}
},
isLocked: (parent: any, __: any, { dataSources, req }: { dataSources: any; req: any }) => isLocked(parent, { dataSources, req })
},
Engagement: {

@ -1,6 +1,7 @@
import { Permission } from '../datasources/userserver/permission';
import { GraphQLError } from 'graphql';
import { isLocked } from '../datasources/db/utils';
import { Participant } from '../model/Participant';
export default {
Query: {
@ -48,6 +49,13 @@ export default {
return new GraphQLError('Insufficient Permissions');
}
},
participants (parent: any, _: any, { dataSources, req }: { dataSources: any; req: any }): Promise<Participant[]> | GraphQLError {
if (req.permissions.includes(Permission.ReadParticipant)) {
return dataSources.workshopAPI.participantsByWorkshopId(parent.id);
} else {
return new GraphQLError('Insufficient Permissions');
}
},
isLocked: (parent: any, __: any, { dataSources, req }: { dataSources: any; req: any }) => isLocked(parent, { dataSources, req })
},
WorkshopType: {

@ -325,6 +325,7 @@ type Participant {
"""
distributedActiveBikeParte: Boolean!
engagement: [Engagement]
workshops: [Workshop]
isLocked: Boolean!
"null if not locked by other user"
lockedBy: ID
@ -344,6 +345,7 @@ input ParticipantCreateInput {
locationZIPs: [String]!
"default: false"
memberCoreTeam: Boolean
workshopIds: [ID]
}
input ParticipantUpdateInput {
@ -360,6 +362,7 @@ input ParticipantUpdateInput {
locationZIPs: [String]
"default: false"
memberCoreTeam: Boolean
workshopIds: [ID]
keepLock: Boolean
}
@ -371,6 +374,7 @@ type Workshop {
workshopType: WorkshopType!
trainer1: Participant!
trainer2: Participant
participants: [Participant]
isLocked: Boolean!
"null if not locked by other user"
lockedBy: ID

Loading…
Cancel
Save