From a496e22a35e747efeb148d9e8116a37b9594cb4f Mon Sep 17 00:00:00 2001 From: tschaffter Date: Wed, 14 Sep 2022 19:52:32 +0000 Subject: [PATCH 01/62] Add auto-generated openapitools.json --- openapitools.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 openapitools.json diff --git a/openapitools.json b/openapitools.json new file mode 100644 index 0000000000..712bf341be --- /dev/null +++ b/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "6.1.0" + } +} From 71f2ce924f1f73e857eddf0ec42a8076e1cae47d Mon Sep 17 00:00:00 2001 From: tschaffter Date: Wed, 14 Sep 2022 20:05:53 +0000 Subject: [PATCH 02/62] Add yarn plugin `outdated` --- .yarn/plugins/@yarnpkg/plugin-outdated.cjs | 33 ++++++++++++++++++++++ .yarnrc.yml | 7 ++++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 .yarn/plugins/@yarnpkg/plugin-outdated.cjs diff --git a/.yarn/plugins/@yarnpkg/plugin-outdated.cjs b/.yarn/plugins/@yarnpkg/plugin-outdated.cjs new file mode 100644 index 0000000000..19eda825a0 --- /dev/null +++ b/.yarn/plugins/@yarnpkg/plugin-outdated.cjs @@ -0,0 +1,33 @@ +/* eslint-disable */ +//prettier-ignore +module.exports = { +name: "@yarnpkg/plugin-outdated", +factory: function (require) { +var plugin=(()=>{var _r=Object.create,ye=Object.defineProperty,xr=Object.defineProperties,br=Object.getOwnPropertyDescriptor,Sr=Object.getOwnPropertyDescriptors,vr=Object.getOwnPropertyNames,tt=Object.getOwnPropertySymbols,Hr=Object.getPrototypeOf,rt=Object.prototype.hasOwnProperty,wr=Object.prototype.propertyIsEnumerable;var nt=(e,t,r)=>t in e?ye(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,w=(e,t)=>{for(var r in t||(t={}))rt.call(t,r)&&nt(e,r,t[r]);if(tt)for(var r of tt(t))wr.call(t,r)&&nt(e,r,t[r]);return e},B=(e,t)=>xr(e,Sr(t)),Tr=e=>ye(e,"__esModule",{value:!0});var W=e=>{if(typeof require!="undefined")return require(e);throw new Error('Dynamic require of "'+e+'" is not supported')};var G=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),$r=(e,t)=>{for(var r in t)ye(e,r,{get:t[r],enumerable:!0})},Lr=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of vr(t))!rt.call(e,n)&&n!=="default"&&ye(e,n,{get:()=>t[n],enumerable:!(r=br(t,n))||r.enumerable});return e},J=e=>Lr(Tr(ye(e!=null?_r(Hr(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var He=G(Y=>{"use strict";Y.isInteger=e=>typeof e=="number"?Number.isInteger(e):typeof e=="string"&&e.trim()!==""?Number.isInteger(Number(e)):!1;Y.find=(e,t)=>e.nodes.find(r=>r.type===t);Y.exceedsLimit=(e,t,r=1,n)=>n===!1||!Y.isInteger(e)||!Y.isInteger(t)?!1:(Number(t)-Number(e))/Number(r)>=n;Y.escapeNode=(e,t=0,r)=>{let n=e.nodes[t];!n||(r&&n.type===r||n.type==="open"||n.type==="close")&&n.escaped!==!0&&(n.value="\\"+n.value,n.escaped=!0)};Y.encloseBrace=e=>e.type!=="brace"?!1:e.commas>>0+e.ranges>>0==0?(e.invalid=!0,!0):!1;Y.isInvalidBrace=e=>e.type!=="brace"?!1:e.invalid===!0||e.dollar?!0:e.commas>>0+e.ranges>>0==0||e.open!==!0||e.close!==!0?(e.invalid=!0,!0):!1;Y.isOpenOrClose=e=>e.type==="open"||e.type==="close"?!0:e.open===!0||e.close===!0;Y.reduce=e=>e.reduce((t,r)=>(r.type==="text"&&t.push(r.value),r.type==="range"&&(r.type="text"),t),[]);Y.flatten=(...e)=>{let t=[],r=n=>{for(let s=0;s{"use strict";var st=He();at.exports=(e,t={})=>{let r=(n,s={})=>{let a=t.escapeInvalid&&st.isInvalidBrace(s),i=n.invalid===!0&&t.escapeInvalid===!0,o="";if(n.value)return(a||i)&&st.isOpenOrClose(n)?"\\"+n.value:n.value;if(n.value)return n.value;if(n.nodes)for(let h of n.nodes)o+=r(h);return o};return r(e)}});var ot=G((ts,it)=>{"use strict";it.exports=function(e){return typeof e=="number"?e-e==0:typeof e=="string"&&e.trim()!==""?Number.isFinite?Number.isFinite(+e):isFinite(+e):!1}});var yt=G((rs,dt)=>{"use strict";var ut=ot(),ce=(e,t,r)=>{if(ut(e)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(t===void 0||e===t)return String(e);if(ut(t)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let n=w({relaxZeros:!0},r);typeof n.strictZeros=="boolean"&&(n.relaxZeros=n.strictZeros===!1);let s=String(n.relaxZeros),a=String(n.shorthand),i=String(n.capture),o=String(n.wrap),h=e+":"+t+"="+s+a+i+o;if(ce.cache.hasOwnProperty(h))return ce.cache[h].result;let d=Math.min(e,t),f=Math.max(e,t);if(Math.abs(d-f)===1){let m=e+"|"+t;return n.capture?`(${m})`:n.wrap===!1?m:`(?:${m})`}let R=gt(e)||gt(t),p={min:e,max:t,a:d,b:f},v=[],A=[];if(R&&(p.isPadded=R,p.maxLen=String(p.max).length),d<0){let m=f<0?Math.abs(f):1;A=ct(m,Math.abs(d),p,n),d=p.a=0}return f>=0&&(v=ct(d,f,p,n)),p.negatives=A,p.positives=v,p.result=Or(A,v,n),n.capture===!0?p.result=`(${p.result})`:n.wrap!==!1&&v.length+A.length>1&&(p.result=`(?:${p.result})`),ce.cache[h]=p,p.result};function Or(e,t,r){let n=De(e,t,"-",!1,r)||[],s=De(t,e,"",!1,r)||[],a=De(e,t,"-?",!0,r)||[];return n.concat(a).concat(s).join("|")}function kr(e,t){let r=1,n=1,s=pt(e,r),a=new Set([t]);for(;e<=s&&s<=t;)a.add(s),r+=1,s=pt(e,r);for(s=ft(t+1,n)-1;e1&&o.count.pop(),o.count.push(f.count[0]),o.string=o.pattern+ht(o.count),i=d+1;continue}r.isPadded&&(R=Mr(d,r,n)),f.string=R+f.pattern+ht(f.count),a.push(f),i=d+1,o=f}return a}function De(e,t,r,n,s){let a=[];for(let i of e){let{string:o}=i;!n&&!lt(t,"string",o)&&a.push(r+o),n&<(t,"string",o)&&a.push(r+o)}return a}function Ir(e,t){let r=[];for(let n=0;nt?1:t>e?-1:0}function lt(e,t,r){return e.some(n=>n[t]===r)}function pt(e,t){return Number(String(e).slice(0,-t)+"9".repeat(t))}function ft(e,t){return e-e%Math.pow(10,t)}function ht(e){let[t=0,r=""]=e;return r||t>1?`{${t+(r?","+r:"")}}`:""}function Pr(e,t,r){return`[${e}${t-e==1?"":"-"}${t}]`}function gt(e){return/^-?(0+)\d/.test(e)}function Mr(e,t,r){if(!t.isPadded)return e;let n=Math.abs(t.maxLen-String(e).length),s=r.relaxZeros!==!1;switch(n){case 0:return"";case 1:return s?"0?":"0";case 2:return s?"0{0,2}":"00";default:return s?`0{0,${n}}`:`0{${n}}`}}ce.cache={};ce.clearCache=()=>ce.cache={};dt.exports=ce});var Be=G((ns,bt)=>{"use strict";var Br=W("util"),Rt=yt(),At=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),Ur=e=>t=>e===!0?Number(t):String(t),Pe=e=>typeof e=="number"||typeof e=="string"&&e!=="",Re=e=>Number.isInteger(+e),Me=e=>{let t=`${e}`,r=-1;if(t[0]==="-"&&(t=t.slice(1)),t==="0")return!1;for(;t[++r]==="0";);return r>0},Gr=(e,t,r)=>typeof e=="string"||typeof t=="string"?!0:r.stringify===!0,Fr=(e,t,r)=>{if(t>0){let n=e[0]==="-"?"-":"";n&&(e=e.slice(1)),e=n+e.padStart(n?t-1:t,"0")}return r===!1?String(e):e},mt=(e,t)=>{let r=e[0]==="-"?"-":"";for(r&&(e=e.slice(1),t--);e.length{e.negatives.sort((i,o)=>io?1:0),e.positives.sort((i,o)=>io?1:0);let r=t.capture?"":"?:",n="",s="",a;return e.positives.length&&(n=e.positives.join("|")),e.negatives.length&&(s=`-(${r}${e.negatives.join("|")})`),n&&s?a=`${n}|${s}`:a=n||s,t.wrap?`(${r}${a})`:a},Ct=(e,t,r,n)=>{if(r)return Rt(e,t,w({wrap:!1},n));let s=String.fromCharCode(e);if(e===t)return s;let a=String.fromCharCode(t);return`[${s}-${a}]`},Et=(e,t,r)=>{if(Array.isArray(e)){let n=r.wrap===!0,s=r.capture?"":"?:";return n?`(${s}${e.join("|")})`:e.join("|")}return Rt(e,t,r)},_t=(...e)=>new RangeError("Invalid range arguments: "+Br.inspect(...e)),xt=(e,t,r)=>{if(r.strictRanges===!0)throw _t([e,t]);return[]},Kr=(e,t)=>{if(t.strictRanges===!0)throw new TypeError(`Expected step "${e}" to be a number`);return[]},qr=(e,t,r=1,n={})=>{let s=Number(e),a=Number(t);if(!Number.isInteger(s)||!Number.isInteger(a)){if(n.strictRanges===!0)throw _t([e,t]);return[]}s===0&&(s=0),a===0&&(a=0);let i=s>a,o=String(e),h=String(t),d=String(r);r=Math.max(Math.abs(r),1);let f=Me(o)||Me(h)||Me(d),R=f?Math.max(o.length,h.length,d.length):0,p=f===!1&&Gr(e,t,n)===!1,v=n.transform||Ur(p);if(n.toRegex&&r===1)return Ct(mt(e,R),mt(t,R),!0,n);let A={negatives:[],positives:[]},m=k=>A[k<0?"negatives":"positives"].push(Math.abs(k)),E=[],b=0;for(;i?s>=a:s<=a;)n.toRegex===!0&&r>1?m(s):E.push(Fr(v(s,b),R,p)),s=i?s-r:s+r,b++;return n.toRegex===!0?r>1?jr(A,n):Et(E,null,w({wrap:!1},n)):E},Wr=(e,t,r=1,n={})=>{if(!Re(e)&&e.length>1||!Re(t)&&t.length>1)return xt(e,t,n);let s=n.transform||(p=>String.fromCharCode(p)),a=`${e}`.charCodeAt(0),i=`${t}`.charCodeAt(0),o=a>i,h=Math.min(a,i),d=Math.max(a,i);if(n.toRegex&&r===1)return Ct(h,d,!1,n);let f=[],R=0;for(;o?a>=i:a<=i;)f.push(s(a,R)),a=o?a-r:a+r,R++;return n.toRegex===!0?Et(f,null,{wrap:!1,options:n}):f},Te=(e,t,r,n={})=>{if(t==null&&Pe(e))return[e];if(!Pe(e)||!Pe(t))return xt(e,t,n);if(typeof r=="function")return Te(e,t,1,{transform:r});if(At(r))return Te(e,t,0,r);let s=w({},n);return s.capture===!0&&(s.wrap=!0),r=r||s.step||1,Re(r)?Re(e)&&Re(t)?qr(e,t,r,s):Wr(e,t,Math.max(Math.abs(r),1),s):r!=null&&!At(r)?Kr(r,s):Te(e,t,1,r)};bt.exports=Te});var Ht=G((ss,vt)=>{"use strict";var Qr=Be(),St=He(),Xr=(e,t={})=>{let r=(n,s={})=>{let a=St.isInvalidBrace(s),i=n.invalid===!0&&t.escapeInvalid===!0,o=a===!0||i===!0,h=t.escapeInvalid===!0?"\\":"",d="";if(n.isOpen===!0||n.isClose===!0)return h+n.value;if(n.type==="open")return o?h+n.value:"(";if(n.type==="close")return o?h+n.value:")";if(n.type==="comma")return n.prev.type==="comma"?"":o?n.value:"|";if(n.value)return n.value;if(n.nodes&&n.ranges>0){let f=St.reduce(n.nodes),R=Qr(...f,B(w({},t),{wrap:!1,toRegex:!0}));if(R.length!==0)return f.length>1&&R.length>1?`(${R})`:R}if(n.nodes)for(let f of n.nodes)d+=r(f,n);return d};return r(e)};vt.exports=Xr});var $t=G((as,Tt)=>{"use strict";var zr=Be(),wt=we(),pe=He(),le=(e="",t="",r=!1)=>{let n=[];if(e=[].concat(e),t=[].concat(t),!t.length)return e;if(!e.length)return r?pe.flatten(t).map(s=>`{${s}}`):t;for(let s of e)if(Array.isArray(s))for(let a of s)n.push(le(a,t,r));else for(let a of t)r===!0&&typeof a=="string"&&(a=`{${a}}`),n.push(Array.isArray(a)?le(s,a,r):s+a);return pe.flatten(n)},Zr=(e,t={})=>{let r=t.rangeLimit===void 0?1e3:t.rangeLimit,n=(s,a={})=>{s.queue=[];let i=a,o=a.queue;for(;i.type!=="brace"&&i.type!=="root"&&i.parent;)i=i.parent,o=i.queue;if(s.invalid||s.dollar){o.push(le(o.pop(),wt(s,t)));return}if(s.type==="brace"&&s.invalid!==!0&&s.nodes.length===2){o.push(le(o.pop(),["{}"]));return}if(s.nodes&&s.ranges>0){let R=pe.reduce(s.nodes);if(pe.exceedsLimit(...R,t.step,r))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let p=zr(...R,t);p.length===0&&(p=wt(s,t)),o.push(le(o.pop(),p)),s.nodes=[];return}let h=pe.encloseBrace(s),d=s.queue,f=s;for(;f.type!=="brace"&&f.type!=="root"&&f.parent;)f=f.parent,d=f.queue;for(let R=0;R{"use strict";Lt.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` +`,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var Pt=G((os,Dt)=>{"use strict";var Vr=we(),{MAX_LENGTH:kt,CHAR_BACKSLASH:Ue,CHAR_BACKTICK:Yr,CHAR_COMMA:Jr,CHAR_DOT:en,CHAR_LEFT_PARENTHESES:tn,CHAR_RIGHT_PARENTHESES:rn,CHAR_LEFT_CURLY_BRACE:nn,CHAR_RIGHT_CURLY_BRACE:sn,CHAR_LEFT_SQUARE_BRACKET:Nt,CHAR_RIGHT_SQUARE_BRACKET:It,CHAR_DOUBLE_QUOTE:an,CHAR_SINGLE_QUOTE:on,CHAR_NO_BREAK_SPACE:un,CHAR_ZERO_WIDTH_NOBREAK_SPACE:cn}=Ot(),ln=(e,t={})=>{if(typeof e!="string")throw new TypeError("Expected a string");let r=t||{},n=typeof r.maxLength=="number"?Math.min(kt,r.maxLength):kt;if(e.length>n)throw new SyntaxError(`Input length (${e.length}), exceeds max characters (${n})`);let s={type:"root",input:e,nodes:[]},a=[s],i=s,o=s,h=0,d=e.length,f=0,R=0,p,v={},A=()=>e[f++],m=E=>{if(E.type==="text"&&o.type==="dot"&&(o.type="text"),o&&o.type==="text"&&E.type==="text"){o.value+=E.value;return}return i.nodes.push(E),E.parent=i,E.prev=o,o=E,E};for(m({type:"bos"});f0){if(i.ranges>0){i.ranges=0;let E=i.nodes.shift();i.nodes=[E,{type:"text",value:Vr(i)}]}m({type:"comma",value:p}),i.commas++;continue}if(p===en&&R>0&&i.commas===0){let E=i.nodes;if(R===0||E.length===0){m({type:"text",value:p});continue}if(o.type==="dot"){if(i.range=[],o.value+=p,o.type="range",i.nodes.length!==3&&i.nodes.length!==5){i.invalid=!0,i.ranges=0,o.type="text";continue}i.ranges++,i.args=[];continue}if(o.type==="range"){E.pop();let b=E[E.length-1];b.value+=o.value+p,o=b,i.ranges--;continue}m({type:"dot",value:p});continue}m({type:"text",value:p})}do if(i=a.pop(),i.type!=="root"){i.nodes.forEach(k=>{k.nodes||(k.type==="open"&&(k.isOpen=!0),k.type==="close"&&(k.isClose=!0),k.nodes||(k.type="text"),k.invalid=!0)});let E=a[a.length-1],b=E.nodes.indexOf(i);E.nodes.splice(b,1,...i.nodes)}while(a.length>0);return m({type:"eos"}),s};Dt.exports=ln});var Ut=G((us,Bt)=>{"use strict";var Mt=we(),pn=Ht(),fn=$t(),hn=Pt(),z=(e,t={})=>{let r=[];if(Array.isArray(e))for(let n of e){let s=z.create(n,t);Array.isArray(s)?r.push(...s):r.push(s)}else r=[].concat(z.create(e,t));return t&&t.expand===!0&&t.nodupes===!0&&(r=[...new Set(r)]),r};z.parse=(e,t={})=>hn(e,t);z.stringify=(e,t={})=>typeof e=="string"?Mt(z.parse(e,t),t):Mt(e,t);z.compile=(e,t={})=>(typeof e=="string"&&(e=z.parse(e,t)),pn(e,t));z.expand=(e,t={})=>{typeof e=="string"&&(e=z.parse(e,t));let r=fn(e,t);return t.noempty===!0&&(r=r.filter(Boolean)),t.nodupes===!0&&(r=[...new Set(r)]),r};z.create=(e,t={})=>e===""||e.length<3?[e]:t.expand!==!0?z.compile(e,t):z.expand(e,t);Bt.exports=z});var Ae=G((cs,qt)=>{"use strict";var gn=W("path"),ne="\\\\/",Gt=`[^${ne}]`,ae="\\.",dn="\\+",yn="\\?",$e="\\/",Rn="(?=.)",Ft="[^/]",Ge=`(?:${$e}|$)`,jt=`(?:^|${$e})`,Fe=`${ae}{1,2}${Ge}`,An=`(?!${ae})`,mn=`(?!${jt}${Fe})`,Cn=`(?!${ae}{0,1}${Ge})`,En=`(?!${Fe})`,_n=`[^.${$e}]`,xn=`${Ft}*?`,Kt={DOT_LITERAL:ae,PLUS_LITERAL:dn,QMARK_LITERAL:yn,SLASH_LITERAL:$e,ONE_CHAR:Rn,QMARK:Ft,END_ANCHOR:Ge,DOTS_SLASH:Fe,NO_DOT:An,NO_DOTS:mn,NO_DOT_SLASH:Cn,NO_DOTS_SLASH:En,QMARK_NO_DOT:_n,STAR:xn,START_ANCHOR:jt},bn=B(w({},Kt),{SLASH_LITERAL:`[${ne}]`,QMARK:Gt,STAR:`${Gt}*?`,DOTS_SLASH:`${ae}{1,2}(?:[${ne}]|$)`,NO_DOT:`(?!${ae})`,NO_DOTS:`(?!(?:^|[${ne}])${ae}{1,2}(?:[${ne}]|$))`,NO_DOT_SLASH:`(?!${ae}{0,1}(?:[${ne}]|$))`,NO_DOTS_SLASH:`(?!${ae}{1,2}(?:[${ne}]|$))`,QMARK_NO_DOT:`[^.${ne}]`,START_ANCHOR:`(?:^|[${ne}])`,END_ANCHOR:`(?:[${ne}]|$)`}),Sn={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};qt.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:Sn,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:gn.sep,extglobChars(e){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${e.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(e){return e===!0?bn:Kt}}});var me=G(Q=>{"use strict";var vn=W("path"),Hn=process.platform==="win32",{REGEX_BACKSLASH:wn,REGEX_REMOVE_BACKSLASH:Tn,REGEX_SPECIAL_CHARS:$n,REGEX_SPECIAL_CHARS_GLOBAL:Ln}=Ae();Q.isObject=e=>e!==null&&typeof e=="object"&&!Array.isArray(e);Q.hasRegexChars=e=>$n.test(e);Q.isRegexChar=e=>e.length===1&&Q.hasRegexChars(e);Q.escapeRegex=e=>e.replace(Ln,"\\$1");Q.toPosixSlashes=e=>e.replace(wn,"/");Q.removeBackslashes=e=>e.replace(Tn,t=>t==="\\"?"":t);Q.supportsLookbehinds=()=>{let e=process.version.slice(1).split(".").map(Number);return e.length===3&&e[0]>=9||e[0]===8&&e[1]>=10};Q.isWindows=e=>e&&typeof e.windows=="boolean"?e.windows:Hn===!0||vn.sep==="\\";Q.escapeLast=(e,t,r)=>{let n=e.lastIndexOf(t,r);return n===-1?e:e[n-1]==="\\"?Q.escapeLast(e,t,n-1):`${e.slice(0,n)}\\${e.slice(n)}`};Q.removePrefix=(e,t={})=>{let r=e;return r.startsWith("./")&&(r=r.slice(2),t.prefix="./"),r};Q.wrapOutput=(e,t={},r={})=>{let n=r.contains?"":"^",s=r.contains?"":"$",a=`${n}(?:${e})${s}`;return t.negated===!0&&(a=`(?:^(?!${a}).*$)`),a}});var Jt=G((ps,Yt)=>{"use strict";var Wt=me(),{CHAR_ASTERISK:je,CHAR_AT:On,CHAR_BACKWARD_SLASH:Ce,CHAR_COMMA:kn,CHAR_DOT:Ke,CHAR_EXCLAMATION_MARK:qe,CHAR_FORWARD_SLASH:Qt,CHAR_LEFT_CURLY_BRACE:We,CHAR_LEFT_PARENTHESES:Qe,CHAR_LEFT_SQUARE_BRACKET:Nn,CHAR_PLUS:In,CHAR_QUESTION_MARK:Xt,CHAR_RIGHT_CURLY_BRACE:Dn,CHAR_RIGHT_PARENTHESES:zt,CHAR_RIGHT_SQUARE_BRACKET:Pn}=Ae(),Zt=e=>e===Qt||e===Ce,Vt=e=>{e.isPrefix!==!0&&(e.depth=e.isGlobstar?Infinity:1)},Mn=(e,t)=>{let r=t||{},n=e.length-1,s=r.parts===!0||r.scanToEnd===!0,a=[],i=[],o=[],h=e,d=-1,f=0,R=0,p=!1,v=!1,A=!1,m=!1,E=!1,b=!1,k=!1,N=!1,ee=!1,F=!1,ie=0,j,C,H={value:"",depth:0,isGlob:!1},U=()=>d>=n,l=()=>h.charCodeAt(d+1),L=()=>(j=C,h.charCodeAt(++d));for(;d0&&(oe=h.slice(0,f),h=h.slice(f),R-=f),T&&A===!0&&R>0?(T=h.slice(0,R),u=h.slice(R)):A===!0?(T="",u=h):T=h,T&&T!==""&&T!=="/"&&T!==h&&Zt(T.charCodeAt(T.length-1))&&(T=T.slice(0,-1)),r.unescape===!0&&(u&&(u=Wt.removeBackslashes(u)),T&&k===!0&&(T=Wt.removeBackslashes(T)));let c={prefix:oe,input:e,start:f,base:T,glob:u,isBrace:p,isBracket:v,isGlob:A,isExtglob:m,isGlobstar:E,negated:N,negatedExtglob:ee};if(r.tokens===!0&&(c.maxDepth=0,Zt(C)||i.push(H),c.tokens=i),r.parts===!0||r.tokens===!0){let K;for(let S=0;S{"use strict";var Le=Ae(),Z=me(),{MAX_LENGTH:Oe,POSIX_REGEX_SOURCE:Bn,REGEX_NON_SPECIAL_CHARS:Un,REGEX_SPECIAL_CHARS_BACKREF:Gn,REPLACEMENTS:er}=Le,Fn=(e,t)=>{if(typeof t.expandRange=="function")return t.expandRange(...e,t);e.sort();let r=`[${e.join("-")}]`;try{new RegExp(r)}catch(n){return e.map(s=>Z.escapeRegex(s)).join("..")}return r},fe=(e,t)=>`Missing ${e}: "${t}" - use "\\\\${t}" to match literal characters`,tr=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");e=er[e]||e;let r=w({},t),n=typeof r.maxLength=="number"?Math.min(Oe,r.maxLength):Oe,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);let a={type:"bos",value:"",output:r.prepend||""},i=[a],o=r.capture?"":"?:",h=Z.isWindows(t),d=Le.globChars(h),f=Le.extglobChars(d),{DOT_LITERAL:R,PLUS_LITERAL:p,SLASH_LITERAL:v,ONE_CHAR:A,DOTS_SLASH:m,NO_DOT:E,NO_DOT_SLASH:b,NO_DOTS_SLASH:k,QMARK:N,QMARK_NO_DOT:ee,STAR:F,START_ANCHOR:ie}=d,j=y=>`(${o}(?:(?!${ie}${y.dot?m:R}).)*?)`,C=r.dot?"":E,H=r.dot?N:ee,U=r.bash===!0?j(r):F;r.capture&&(U=`(${U})`),typeof r.noext=="boolean"&&(r.noextglob=r.noext);let l={input:e,index:-1,start:0,dot:r.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:i};e=Z.removePrefix(e,l),s=e.length;let L=[],T=[],oe=[],u=a,c,K=()=>l.index===s-1,S=l.peek=(y=1)=>e[l.index+y],te=l.advance=()=>e[++l.index]||"",re=()=>e.slice(l.index+1),X=(y="",$=0)=>{l.consumed+=y,l.index+=$},xe=y=>{l.output+=y.output!=null?y.output:y.value,X(y.value)},Cr=()=>{let y=1;for(;S()==="!"&&(S(2)!=="("||S(3)==="?");)te(),l.start++,y++;return y%2==0?!1:(l.negated=!0,l.start++,!0)},be=y=>{l[y]++,oe.push(y)},ue=y=>{l[y]--,oe.pop()},x=y=>{if(u.type==="globstar"){let $=l.braces>0&&(y.type==="comma"||y.type==="brace"),g=y.extglob===!0||L.length&&(y.type==="pipe"||y.type==="paren");y.type!=="slash"&&y.type!=="paren"&&!$&&!g&&(l.output=l.output.slice(0,-u.output.length),u.type="star",u.value="*",u.output=U,l.output+=u.output)}if(L.length&&y.type!=="paren"&&(L[L.length-1].inner+=y.value),(y.value||y.output)&&xe(y),u&&u.type==="text"&&y.type==="text"){u.value+=y.value,u.output=(u.output||"")+y.value;return}y.prev=u,i.push(y),u=y},Se=(y,$)=>{let g=B(w({},f[$]),{conditions:1,inner:""});g.prev=u,g.parens=l.parens,g.output=l.output;let _=(r.capture?"(":"")+g.open;be("parens"),x({type:y,value:$,output:l.output?"":A}),x({type:"paren",extglob:!0,value:te(),output:_}),L.push(g)},Er=y=>{let $=y.close+(r.capture?")":""),g;if(y.type==="negate"){let _=U;y.inner&&y.inner.length>1&&y.inner.includes("/")&&(_=j(r)),(_!==U||K()||/^\)+$/.test(re()))&&($=y.close=`)$))${_}`),y.inner.includes("*")&&(g=re())&&/^\.[^\\/.]+$/.test(g)&&($=y.close=`)${g})${_})`),y.prev.type==="bos"&&(l.negatedExtglob=!0)}x({type:"paren",extglob:!0,value:c,output:$}),ue("parens")};if(r.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(e)){let y=!1,$=e.replace(Gn,(g,_,I,q,M,Ie)=>q==="\\"?(y=!0,g):q==="?"?_?_+q+(M?N.repeat(M.length):""):Ie===0?H+(M?N.repeat(M.length):""):N.repeat(I.length):q==="."?R.repeat(I.length):q==="*"?_?_+q+(M?U:""):U:_?g:`\\${g}`);return y===!0&&(r.unescape===!0?$=$.replace(/\\/g,""):$=$.replace(/\\+/g,g=>g.length%2==0?"\\\\":g?"\\":"")),$===e&&r.contains===!0?(l.output=e,l):(l.output=Z.wrapOutput($,l,t),l)}for(;!K();){if(c=te(),c==="\0")continue;if(c==="\\"){let g=S();if(g==="/"&&r.bash!==!0||g==="."||g===";")continue;if(!g){c+="\\",x({type:"text",value:c});continue}let _=/^\\+/.exec(re()),I=0;if(_&&_[0].length>2&&(I=_[0].length,l.index+=I,I%2!=0&&(c+="\\")),r.unescape===!0?c=te():c+=te(),l.brackets===0){x({type:"text",value:c});continue}}if(l.brackets>0&&(c!=="]"||u.value==="["||u.value==="[^")){if(r.posix!==!1&&c===":"){let g=u.value.slice(1);if(g.includes("[")&&(u.posix=!0,g.includes(":"))){let _=u.value.lastIndexOf("["),I=u.value.slice(0,_),q=u.value.slice(_+2),M=Bn[q];if(M){u.value=I+M,l.backtrack=!0,te(),!a.output&&i.indexOf(u)===1&&(a.output=A);continue}}}(c==="["&&S()!==":"||c==="-"&&S()==="]")&&(c=`\\${c}`),c==="]"&&(u.value==="["||u.value==="[^")&&(c=`\\${c}`),r.posix===!0&&c==="!"&&u.value==="["&&(c="^"),u.value+=c,xe({value:c});continue}if(l.quotes===1&&c!=='"'){c=Z.escapeRegex(c),u.value+=c,xe({value:c});continue}if(c==='"'){l.quotes=l.quotes===1?0:1,r.keepQuotes===!0&&x({type:"text",value:c});continue}if(c==="("){be("parens"),x({type:"paren",value:c});continue}if(c===")"){if(l.parens===0&&r.strictBrackets===!0)throw new SyntaxError(fe("opening","("));let g=L[L.length-1];if(g&&l.parens===g.parens+1){Er(L.pop());continue}x({type:"paren",value:c,output:l.parens?")":"\\)"}),ue("parens");continue}if(c==="["){if(r.nobracket===!0||!re().includes("]")){if(r.nobracket!==!0&&r.strictBrackets===!0)throw new SyntaxError(fe("closing","]"));c=`\\${c}`}else be("brackets");x({type:"bracket",value:c});continue}if(c==="]"){if(r.nobracket===!0||u&&u.type==="bracket"&&u.value.length===1){x({type:"text",value:c,output:`\\${c}`});continue}if(l.brackets===0){if(r.strictBrackets===!0)throw new SyntaxError(fe("opening","["));x({type:"text",value:c,output:`\\${c}`});continue}ue("brackets");let g=u.value.slice(1);if(u.posix!==!0&&g[0]==="^"&&!g.includes("/")&&(c=`/${c}`),u.value+=c,xe({value:c}),r.literalBrackets===!1||Z.hasRegexChars(g))continue;let _=Z.escapeRegex(u.value);if(l.output=l.output.slice(0,-u.value.length),r.literalBrackets===!0){l.output+=_,u.value=_;continue}u.value=`(${o}${_}|${u.value})`,l.output+=u.value;continue}if(c==="{"&&r.nobrace!==!0){be("braces");let g={type:"brace",value:c,output:"(",outputIndex:l.output.length,tokensIndex:l.tokens.length};T.push(g),x(g);continue}if(c==="}"){let g=T[T.length-1];if(r.nobrace===!0||!g){x({type:"text",value:c,output:c});continue}let _=")";if(g.dots===!0){let I=i.slice(),q=[];for(let M=I.length-1;M>=0&&(i.pop(),I[M].type!=="brace");M--)I[M].type!=="dots"&&q.unshift(I[M].value);_=Fn(q,r),l.backtrack=!0}if(g.comma!==!0&&g.dots!==!0){let I=l.output.slice(0,g.outputIndex),q=l.tokens.slice(g.tokensIndex);g.value=g.output="\\{",c=_="\\}",l.output=I;for(let M of q)l.output+=M.output||M.value}x({type:"brace",value:c,output:_}),ue("braces"),T.pop();continue}if(c==="|"){L.length>0&&L[L.length-1].conditions++,x({type:"text",value:c});continue}if(c===","){let g=c,_=T[T.length-1];_&&oe[oe.length-1]==="braces"&&(_.comma=!0,g="|"),x({type:"comma",value:c,output:g});continue}if(c==="/"){if(u.type==="dot"&&l.index===l.start+1){l.start=l.index+1,l.consumed="",l.output="",i.pop(),u=a;continue}x({type:"slash",value:c,output:v});continue}if(c==="."){if(l.braces>0&&u.type==="dot"){u.value==="."&&(u.output=R);let g=T[T.length-1];u.type="dots",u.output+=c,u.value+=c,g.dots=!0;continue}if(l.braces+l.parens===0&&u.type!=="bos"&&u.type!=="slash"){x({type:"text",value:c,output:R});continue}x({type:"dot",value:c,output:R});continue}if(c==="?"){if(!(u&&u.value==="(")&&r.noextglob!==!0&&S()==="("&&S(2)!=="?"){Se("qmark",c);continue}if(u&&u.type==="paren"){let _=S(),I=c;if(_==="<"&&!Z.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(u.value==="("&&!/[!=<:]/.test(_)||_==="<"&&!/<([!=]|\w+>)/.test(re()))&&(I=`\\${c}`),x({type:"text",value:c,output:I});continue}if(r.dot!==!0&&(u.type==="slash"||u.type==="bos")){x({type:"qmark",value:c,output:ee});continue}x({type:"qmark",value:c,output:N});continue}if(c==="!"){if(r.noextglob!==!0&&S()==="("&&(S(2)!=="?"||!/[!=<:]/.test(S(3)))){Se("negate",c);continue}if(r.nonegate!==!0&&l.index===0){Cr();continue}}if(c==="+"){if(r.noextglob!==!0&&S()==="("&&S(2)!=="?"){Se("plus",c);continue}if(u&&u.value==="("||r.regex===!1){x({type:"plus",value:c,output:p});continue}if(u&&(u.type==="bracket"||u.type==="paren"||u.type==="brace")||l.parens>0){x({type:"plus",value:c});continue}x({type:"plus",value:p});continue}if(c==="@"){if(r.noextglob!==!0&&S()==="("&&S(2)!=="?"){x({type:"at",extglob:!0,value:c,output:""});continue}x({type:"text",value:c});continue}if(c!=="*"){(c==="$"||c==="^")&&(c=`\\${c}`);let g=Un.exec(re());g&&(c+=g[0],l.index+=g[0].length),x({type:"text",value:c});continue}if(u&&(u.type==="globstar"||u.star===!0)){u.type="star",u.star=!0,u.value+=c,u.output=U,l.backtrack=!0,l.globstar=!0,X(c);continue}let y=re();if(r.noextglob!==!0&&/^\([^?]/.test(y)){Se("star",c);continue}if(u.type==="star"){if(r.noglobstar===!0){X(c);continue}let g=u.prev,_=g.prev,I=g.type==="slash"||g.type==="bos",q=_&&(_.type==="star"||_.type==="globstar");if(r.bash===!0&&(!I||y[0]&&y[0]!=="/")){x({type:"star",value:c,output:""});continue}let M=l.braces>0&&(g.type==="comma"||g.type==="brace"),Ie=L.length&&(g.type==="pipe"||g.type==="paren");if(!I&&g.type!=="paren"&&!M&&!Ie){x({type:"star",value:c,output:""});continue}for(;y.slice(0,3)==="/**";){let ve=e[l.index+4];if(ve&&ve!=="/")break;y=y.slice(3),X("/**",3)}if(g.type==="bos"&&K()){u.type="globstar",u.value+=c,u.output=j(r),l.output=u.output,l.globstar=!0,X(c);continue}if(g.type==="slash"&&g.prev.type!=="bos"&&!q&&K()){l.output=l.output.slice(0,-(g.output+u.output).length),g.output=`(?:${g.output}`,u.type="globstar",u.output=j(r)+(r.strictSlashes?")":"|$)"),u.value+=c,l.globstar=!0,l.output+=g.output+u.output,X(c);continue}if(g.type==="slash"&&g.prev.type!=="bos"&&y[0]==="/"){let ve=y[1]!==void 0?"|$":"";l.output=l.output.slice(0,-(g.output+u.output).length),g.output=`(?:${g.output}`,u.type="globstar",u.output=`${j(r)}${v}|${v}${ve})`,u.value+=c,l.output+=g.output+u.output,l.globstar=!0,X(c+te()),x({type:"slash",value:"/",output:""});continue}if(g.type==="bos"&&y[0]==="/"){u.type="globstar",u.value+=c,u.output=`(?:^|${v}|${j(r)}${v})`,l.output=u.output,l.globstar=!0,X(c+te()),x({type:"slash",value:"/",output:""});continue}l.output=l.output.slice(0,-u.output.length),u.type="globstar",u.output=j(r),u.value+=c,l.output+=u.output,l.globstar=!0,X(c);continue}let $={type:"star",value:c,output:U};if(r.bash===!0){$.output=".*?",(u.type==="bos"||u.type==="slash")&&($.output=C+$.output),x($);continue}if(u&&(u.type==="bracket"||u.type==="paren")&&r.regex===!0){$.output=c,x($);continue}(l.index===l.start||u.type==="slash"||u.type==="dot")&&(u.type==="dot"?(l.output+=b,u.output+=b):r.dot===!0?(l.output+=k,u.output+=k):(l.output+=C,u.output+=C),S()!=="*"&&(l.output+=A,u.output+=A)),x($)}for(;l.brackets>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing","]"));l.output=Z.escapeLast(l.output,"["),ue("brackets")}for(;l.parens>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing",")"));l.output=Z.escapeLast(l.output,"("),ue("parens")}for(;l.braces>0;){if(r.strictBrackets===!0)throw new SyntaxError(fe("closing","}"));l.output=Z.escapeLast(l.output,"{"),ue("braces")}if(r.strictSlashes!==!0&&(u.type==="star"||u.type==="bracket")&&x({type:"maybe_slash",value:"",output:`${v}?`}),l.backtrack===!0){l.output="";for(let y of l.tokens)l.output+=y.output!=null?y.output:y.value,y.suffix&&(l.output+=y.suffix)}return l};tr.fastpaths=(e,t)=>{let r=w({},t),n=typeof r.maxLength=="number"?Math.min(Oe,r.maxLength):Oe,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);e=er[e]||e;let a=Z.isWindows(t),{DOT_LITERAL:i,SLASH_LITERAL:o,ONE_CHAR:h,DOTS_SLASH:d,NO_DOT:f,NO_DOTS:R,NO_DOTS_SLASH:p,STAR:v,START_ANCHOR:A}=Le.globChars(a),m=r.dot?R:f,E=r.dot?p:f,b=r.capture?"":"?:",k={negated:!1,prefix:""},N=r.bash===!0?".*?":v;r.capture&&(N=`(${N})`);let ee=C=>C.noglobstar===!0?N:`(${b}(?:(?!${A}${C.dot?d:i}).)*?)`,F=C=>{switch(C){case"*":return`${m}${h}${N}`;case".*":return`${i}${h}${N}`;case"*.*":return`${m}${N}${i}${h}${N}`;case"*/*":return`${m}${N}${o}${h}${E}${N}`;case"**":return m+ee(r);case"**/*":return`(?:${m}${ee(r)}${o})?${E}${h}${N}`;case"**/*.*":return`(?:${m}${ee(r)}${o})?${E}${N}${i}${h}${N}`;case"**/.*":return`(?:${m}${ee(r)}${o})?${i}${h}${N}`;default:{let H=/^(.*?)\.(\w+)$/.exec(C);if(!H)return;let U=F(H[1]);return U?U+i+H[2]:void 0}}},ie=Z.removePrefix(e,k),j=F(ie);return j&&r.strictSlashes!==!0&&(j+=`${o}?`),j};rr.exports=tr});var ar=G((hs,sr)=>{"use strict";var jn=W("path"),Kn=Jt(),Xe=nr(),ze=me(),qn=Ae(),Wn=e=>e&&typeof e=="object"&&!Array.isArray(e),D=(e,t,r=!1)=>{if(Array.isArray(e)){let f=e.map(p=>D(p,t,r));return p=>{for(let v of f){let A=v(p);if(A)return A}return!1}}let n=Wn(e)&&e.tokens&&e.input;if(e===""||typeof e!="string"&&!n)throw new TypeError("Expected pattern to be a non-empty string");let s=t||{},a=ze.isWindows(t),i=n?D.compileRe(e,t):D.makeRe(e,t,!1,!0),o=i.state;delete i.state;let h=()=>!1;if(s.ignore){let f=B(w({},t),{ignore:null,onMatch:null,onResult:null});h=D(s.ignore,f,r)}let d=(f,R=!1)=>{let{isMatch:p,match:v,output:A}=D.test(f,i,t,{glob:e,posix:a}),m={glob:e,state:o,regex:i,posix:a,input:f,output:A,match:v,isMatch:p};return typeof s.onResult=="function"&&s.onResult(m),p===!1?(m.isMatch=!1,R?m:!1):h(f)?(typeof s.onIgnore=="function"&&s.onIgnore(m),m.isMatch=!1,R?m:!1):(typeof s.onMatch=="function"&&s.onMatch(m),R?m:!0)};return r&&(d.state=o),d};D.test=(e,t,r,{glob:n,posix:s}={})=>{if(typeof e!="string")throw new TypeError("Expected input to be a string");if(e==="")return{isMatch:!1,output:""};let a=r||{},i=a.format||(s?ze.toPosixSlashes:null),o=e===n,h=o&&i?i(e):e;return o===!1&&(h=i?i(e):e,o=h===n),(o===!1||a.capture===!0)&&(a.matchBase===!0||a.basename===!0?o=D.matchBase(e,t,r,s):o=t.exec(h)),{isMatch:Boolean(o),match:o,output:h}};D.matchBase=(e,t,r,n=ze.isWindows(r))=>(t instanceof RegExp?t:D.makeRe(t,r)).test(jn.basename(e));D.isMatch=(e,t,r)=>D(t,r)(e);D.parse=(e,t)=>Array.isArray(e)?e.map(r=>D.parse(r,t)):Xe(e,B(w({},t),{fastpaths:!1}));D.scan=(e,t)=>Kn(e,t);D.compileRe=(e,t,r=!1,n=!1)=>{if(r===!0)return e.output;let s=t||{},a=s.contains?"":"^",i=s.contains?"":"$",o=`${a}(?:${e.output})${i}`;e&&e.negated===!0&&(o=`^(?!${o}).*$`);let h=D.toRegex(o,t);return n===!0&&(h.state=e),h};D.makeRe=(e,t={},r=!1,n=!1)=>{if(!e||typeof e!="string")throw new TypeError("Expected a non-empty string");let s={negated:!1,fastpaths:!0};return t.fastpaths!==!1&&(e[0]==="."||e[0]==="*")&&(s.output=Xe.fastpaths(e,t)),s.output||(s=Xe(e,t)),D.compileRe(s,t,r,n)};D.toRegex=(e,t)=>{try{let r=t||{};return new RegExp(e,r.flags||(r.nocase?"i":""))}catch(r){if(t&&t.debug===!0)throw r;return/$^/}};D.constants=qn;sr.exports=D});var or=G((gs,ir)=>{"use strict";ir.exports=ar()});var fr=G((ds,pr)=>{"use strict";var ur=W("util"),cr=Ut(),se=or(),Ze=me(),lr=e=>e===""||e==="./",O=(e,t,r)=>{t=[].concat(t),e=[].concat(e);let n=new Set,s=new Set,a=new Set,i=0,o=f=>{a.add(f.output),r&&r.onResult&&r.onResult(f)};for(let f=0;f!n.has(f));if(r&&d.length===0){if(r.failglob===!0)throw new Error(`No matches found for "${t.join(", ")}"`);if(r.nonull===!0||r.nullglob===!0)return r.unescape?t.map(f=>f.replace(/\\/g,"")):t}return d};O.match=O;O.matcher=(e,t)=>se(e,t);O.isMatch=(e,t,r)=>se(t,r)(e);O.any=O.isMatch;O.not=(e,t,r={})=>{t=[].concat(t).map(String);let n=new Set,s=[],a=o=>{r.onResult&&r.onResult(o),s.push(o.output)},i=O(e,t,B(w({},r),{onResult:a}));for(let o of s)i.includes(o)||n.add(o);return[...n]};O.contains=(e,t,r)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${ur.inspect(e)}"`);if(Array.isArray(t))return t.some(n=>O.contains(e,n,r));if(typeof t=="string"){if(lr(e)||lr(t))return!1;if(e.includes(t)||e.startsWith("./")&&e.slice(2).includes(t))return!0}return O.isMatch(e,t,B(w({},r),{contains:!0}))};O.matchKeys=(e,t,r)=>{if(!Ze.isObject(e))throw new TypeError("Expected the first argument to be an object");let n=O(Object.keys(e),t,r),s={};for(let a of n)s[a]=e[a];return s};O.some=(e,t,r)=>{let n=[].concat(e);for(let s of[].concat(t)){let a=se(String(s),r);if(n.some(i=>a(i)))return!0}return!1};O.every=(e,t,r)=>{let n=[].concat(e);for(let s of[].concat(t)){let a=se(String(s),r);if(!n.every(i=>a(i)))return!1}return!0};O.all=(e,t,r)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${ur.inspect(e)}"`);return[].concat(t).every(n=>se(n,r)(e))};O.capture=(e,t,r)=>{let n=Ze.isWindows(r),a=se.makeRe(String(e),B(w({},r),{capture:!0})).exec(n?Ze.toPosixSlashes(t):t);if(a)return a.slice(1).map(i=>i===void 0?"":i)};O.makeRe=(...e)=>se.makeRe(...e);O.scan=(...e)=>se.scan(...e);O.parse=(e,t)=>{let r=[];for(let n of[].concat(e||[]))for(let s of cr(String(n),t))r.push(se.parse(s,t));return r};O.braces=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");return t&&t.nobrace===!0||!/\{.*\}/.test(e)?[e]:cr(e,t)};O.braceExpand=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");return O.braces(e,B(w({},t),{expand:!0}))};pr.exports=O});var Vn={};$r(Vn,{default:()=>Zn});var ke=J(W("@yarnpkg/cli")),P=J(W("@yarnpkg/core")),V=J(W("clipanion")),et=J(fr()),mr=J(W("path")),Ne=J(W("semver")),de=J(W("typanion"));var he=J(W("@yarnpkg/core")),yr=J(W("@yarnpkg/plugin-essentials"));var Ee=J(W("semver")),hr=Boolean;function Qn(e){var s;let[t,r,n]=(s=e.match(/(github|bitbucket|gitlab):(.+)/))!=null?s:[];return r?`https://${r}.${r==="bitbucket"?"org":"com"}/${n}`:`https://github.com/${e}`}function gr(e){let{homepage:t,repository:r}=e.raw;return t||(typeof r=="string"?Qn(r):r==null?void 0:r.url)}function dr(e,t){return Ee.default.parse(t).prerelease.length?Ee.default.lt(e,t):Ee.default.lt(Ee.default.coerce(e),t)}var Ve=class{constructor(t,r,n,s){this.configuration=t;this.project=r;this.workspace=n;this.cache=s}async fetch({descriptor:t,includeRange:r,includeURL:n,pkg:s}){let[a,i,o]=await Promise.all([this.suggest(s,"latest"),r?this.suggest(s,t.range):Promise.resolve(),n?this.fetchURL(s):Promise.resolve()]);if(!a){let h=he.structUtils.prettyIdent(this.configuration,s);throw new Error(`Could not fetch candidate for ${h}.`)}return{latest:a.range,range:i==null?void 0:i.range,url:o}}suggest(t,r){return yr.suggestUtils.fetchDescriptorFrom(t,r,{cache:this.cache,preserveModifier:!1,project:this.project,workspace:this.workspace})}async fetchURL(t){var a;let r=this.configuration.makeFetcher(),n=await r.fetch(t,{cache:this.cache,checksums:this.project.storedChecksums,fetcher:r,project:this.project,report:new he.ThrowReport,skipIntegrityCheck:!0}),s;try{s=await he.Manifest.find(n.prefixPath,{baseFs:n.packageFs})}finally{(a=n.releaseFs)==null||a.call(n)}return gr(s)}};var ge=J(W("@yarnpkg/core")),Xn=/^([0-9]+\.)([0-9]+\.)(.+)$/,Rr=["name","current","range","latest","workspace","type","url"],Ye=class{constructor(t,r,n,s){this.report=t;this.configuration=r;this.dependencies=n;this.extraColumns=s;this.sizes=null;this.headers={current:"Current",latest:"Latest",name:"Package",range:"Range",type:"Package Type",url:"URL",workspace:"Workspace"}}print(){this.sizes=this.getColumnSizes(),this.printHeader(),this.dependencies.forEach(t=>{var s,a;let r=this.getDiffColor(t.severity.latest),n=this.getDiffColor(t.severity.range);this.printRow({current:t.current.padEnd(this.sizes.current),latest:this.formatVersion(t,"latest",r),name:this.applyColor(t.name.padEnd(this.sizes.name),r),range:this.formatVersion(t,"range",n),type:t.type.padEnd(this.sizes.type),url:(s=t.url)==null?void 0:s.padEnd(this.sizes.url),workspace:(a=t.workspace)==null?void 0:a.padEnd(this.sizes.workspace)})})}applyColor(t,r){return r?ge.formatUtils.pretty(this.configuration,t,r):t}formatVersion(t,r,n){var d;let s=(d=t[r])==null?void 0:d.padEnd(this.sizes[r]);if(!s)return;let a=s.match(Xn);if(!a||!n)return s;let i=["red","yellow","green"].indexOf(n)+1,o=a.slice(1,i).join(""),h=a.slice(i).join("");return o+ge.formatUtils.pretty(this.configuration,this.applyColor(h,n),"bold")}getDiffColor(t){return t?{major:"red",minor:"yellow",patch:"green"}[t]:null}getColumnSizes(){let t=Rr.reduce((r,n)=>B(w({},r),{[n]:this.headers[n].length}),{});for(let r of this.dependencies)for(let[n,s]of Object.entries(r)){let a=t[n],i=(s||"").length;t[n]=a>i?a:i}return t}formatColumnHeader(t){return ge.formatUtils.pretty(this.configuration,this.headers[t].padEnd(this.sizes[t]),"bold")}printHeader(){this.printRow({current:this.formatColumnHeader("current"),latest:this.formatColumnHeader("latest"),name:this.formatColumnHeader("name"),range:this.formatColumnHeader("range"),type:this.formatColumnHeader("type"),url:this.formatColumnHeader("url"),workspace:this.formatColumnHeader("workspace")})}printRow(t){let r=Rr.filter(n=>{var s;return(s=this.extraColumns[n])!=null?s:!0}).map(n=>t[n]).join(" ").trim();this.report.reportInfo(ge.MessageName.UNNAMED,r)}};var Je=["dependencies","devDependencies"],Ar=["major","minor","patch"];var _e=class extends ke.BaseCommand{constructor(){super(...arguments);this.patterns=V.Option.Rest();this.workspace=V.Option.Array("-w,--workspace",{description:"Only search for dependencies in the specified workspaces. If no workspaces are specified, only searches for outdated dependencies in the current workspace.",validator:de.default.isArray(de.default.isString())});this.check=V.Option.Boolean("-c,--check",!1,{description:"Exit with exit code 1 when outdated dependencies are found"});this.json=V.Option.Boolean("--json",!1,{description:"Format the output as JSON"});this.severity=V.Option.Array("-s,--severity",{description:"Filter results based on the severity of the update",validator:de.default.isArray(de.default.isEnum(Ar))});this.type=V.Option.String("-t,--type",{description:"Filter results based on the dependency type",validator:de.default.isEnum(Je)});this.includeURL=V.Option.Boolean("--url",!1,{description:"Include the homepage URL of each package in the output"});this.includeRange=V.Option.Boolean("--range",!1,{description:"Include the latest version of the package which satisfies the current range specified in the manifest."})}async execute(){let{cache:t,configuration:r,project:n,workspace:s}=await this.loadProject(),a=new Ve(r,n,s,t),i=this.getWorkspaces(n),o=this.getDependencies(r,i);if(this.json){let f=(await this.getOutdatedDependencies(n,a,o)).map(R=>B(w({},R),{severity:R.severity.latest}));this.context.stdout.write(JSON.stringify(f)+` +`);return}return(await P.StreamReport.start({configuration:r,stdout:this.context.stdout},async d=>{await this.checkOutdatedDependencies(r,n,o,a,d)})).exitCode()}async checkOutdatedDependencies(t,r,n,s,a){let i=null;await a.startTimerPromise("Checking for outdated dependencies",async()=>{let o=n.length,h=P.StreamReport.progressViaCounter(o);a.reportProgress(h),i=await this.getOutdatedDependencies(r,s,n,h)}),a.reportSeparator(),i.length?(new Ye(a,t,i,{range:this.includeRange,url:this.includeURL,workspace:this.includeWorkspace(r)}).print(),a.reportSeparator(),this.printOutdatedCount(a,i.length)):this.printUpToDate(t,a)}async loadProject(){let t=await P.Configuration.find(this.context.cwd,this.context.plugins),[r,{project:n,workspace:s}]=await Promise.all([P.Cache.find(t),P.Project.find(t,this.context.cwd)]);if(await n.restoreInstallState(),!s)throw new ke.WorkspaceRequiredError(n.cwd,this.context.cwd);return{cache:r,configuration:t,project:n,workspace:s}}getWorkspaces(t){let r=this.workspace;return r?r[0]==="."?t.workspaces.filter(n=>n.cwd===this.context.cwd):t.workspaces.filter(n=>{let s=[...r,...r.map(a=>mr.default.join(this.context.cwd,a))];return et.default.some([this.getWorkspaceName(n),n.cwd],s)}):t.workspaces}includeWorkspace(t){return t.workspaces.length>1}get dependencyTypes(){return this.type?[this.type]:Je}getDependencies(t,r){let n=[];for(let a of r){let{anchoredLocator:i,project:o}=a,h=o.storedPackages.get(i.locatorHash);h||this.throw(t,i);for(let d of this.dependencyTypes)for(let f of a.manifest[d].values()){let{range:R}=f;if(R.includes(":")&&!/(npm|patch):/.test(R))continue;let p=h.dependencies.get(f.identHash);p||this.throw(t,f);let v=o.storedResolutions.get(p.descriptorHash);v||this.throw(t,p);let A=o.storedPackages.get(v);A||this.throw(t,p),!a.project.tryWorkspaceByLocator(A)&&(A.reference.includes("github.com")||n.push({dependencyType:d,descriptor:f,name:P.structUtils.stringifyIdent(f),pkg:A,workspace:a}))}}if(!this.patterns.length)return n;let s=n.filter(({name:a})=>et.default.isMatch(a,this.patterns));if(!s.length)throw new V.UsageError(`Pattern ${P.formatUtils.prettyList(t,this.patterns,P.FormatType.CODE)} doesn't match any packages referenced by any workspace`);return s}throw(t,r){let n=P.structUtils.prettyIdent(t,r);throw new Error(`Package for ${n} not found in the project`)}getSeverity(t,r){let n=Ne.default.coerce(t),s=Ne.default.coerce(r);return Ne.default.eq(n,s)?null:n.major===0||s.major>n.major?"major":s.minor>n.minor?"minor":"patch"}async getOutdatedDependencies(t,r,n,s){let a=n.map(async({dependencyType:i,descriptor:o,name:h,pkg:d,workspace:f})=>{let{latest:R,range:p,url:v}=await r.fetch({descriptor:o,includeRange:this.includeRange,includeURL:this.includeURL,pkg:d});if(s==null||s.tick(),dr(d.version,R))return{current:d.version,latest:R,name:h,range:p,severity:{latest:this.getSeverity(d.version,R),range:p?this.getSeverity(d.version,p):null},type:i,url:v,workspace:this.includeWorkspace(t)?this.getWorkspaceName(f):void 0}});return(await Promise.all(a)).filter(hr).filter(i=>{var o,h;return(h=(o=this.severity)==null?void 0:o.includes(i.severity.latest))!=null?h:!0}).sort((i,o)=>i.name.localeCompare(o.name))}getWorkspaceName(t){return t.manifest.name?P.structUtils.stringifyIdent(t.manifest.name):t.computeCandidateName()}printOutdatedCount(t,r){let n=[P.MessageName.UNNAMED,r===1?"1 dependency is out of date":`${r} dependencies are out of date`];this.check?t.reportError(...n):t.reportWarning(...n)}printUpToDate(t,r){let n="\u2728 All your dependencies are up to date!";r.reportInfo(P.MessageName.UNNAMED,P.formatUtils.pretty(t,n,"green"))}};_e.paths=[["outdated"]],_e.usage=V.Command.Usage({description:"view outdated dependencies",details:` + This command finds outdated dependencies in a project and prints the result in a table or JSON format. + + This command accepts glob patterns as arguments to filter the output. Make sure to escape the patterns, to prevent your own shell from trying to expand them. + `,examples:[["View outdated dependencies","yarn outdated"],["View outdated dependencies with the `@babel` scope","yarn outdated '@babel/*'"],["Filter results to only include devDependencies","yarn outdated --type devDependencies"],["Filter results to only include major version updates","yarn outdated --severity major"]]});var zn={commands:[_e]},Zn=zn;return Vn;})(); +/*! + * fill-range + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Licensed under the MIT License. + */ +/*! + * is-number + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * to-regex-range + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + */ +return plugin; +} +}; diff --git a/.yarnrc.yml b/.yarnrc.yml index 2c56d2db68..e1a6a0643e 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -1,2 +1,7 @@ +nodeLinker: node-modules + +plugins: + - path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs + spec: "https://mskelton.dev/yarn-outdated/v3" + yarnPath: .yarn/releases/yarn-3.2.2.cjs -nodeLinker: node-modules \ No newline at end of file From f9044b057fe100fdf3061a748fba530e99c1d840 Mon Sep 17 00:00:00 2001 From: tschaffter Date: Wed, 14 Sep 2022 23:55:21 +0000 Subject: [PATCH 03/62] Generate API stub for Spring Boot --- .../challenge-user-service/generate-server.sh | 6 + .../challenge-user-service/openapitools.json | 0 .../server/.openapi-generator-ignore | 23 ++ .../server/.openapi-generator/FILES | 15 ++ .../server/.openapi-generator/VERSION | 1 + apps/challenge-user-service/server/README.md | 21 ++ apps/challenge-user-service/server/pom.xml | 80 ++++++ .../OpenApiGeneratorApplication.java | 23 ++ .../org/openapitools/RFC3339DateFormat.java | 38 +++ .../java/org/openapitools/api/ApiApi.java | 198 ++++++++++++++ .../openapitools/api/ApiApiController.java | 46 ++++ .../java/org/openapitools/api/ApiUtil.java | 19 ++ .../configuration/HomeController.java | 20 ++ .../configuration/SpringDocConfiguration.java | 38 +++ .../java/org/openapitools/model/User.java | 243 ++++++++++++++++++ .../openapitools/model/UserUpdateRequest.java | 123 +++++++++ .../src/main/resources/application.properties | 3 + .../server/src/main/resources/openapi.yaml | 183 +++++++++++++ .../OpenApiGeneratorApplicationTests.java | 13 + 19 files changed, 1093 insertions(+) create mode 100755 apps/challenge-user-service/generate-server.sh rename openapitools.json => apps/challenge-user-service/openapitools.json (100%) create mode 100644 apps/challenge-user-service/server/.openapi-generator-ignore create mode 100644 apps/challenge-user-service/server/.openapi-generator/FILES create mode 100644 apps/challenge-user-service/server/.openapi-generator/VERSION create mode 100644 apps/challenge-user-service/server/README.md create mode 100644 apps/challenge-user-service/server/pom.xml create mode 100644 apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java create mode 100644 apps/challenge-user-service/server/src/main/java/org/openapitools/RFC3339DateFormat.java create mode 100644 apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApi.java create mode 100644 apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApiController.java create mode 100644 apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiUtil.java create mode 100644 apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/HomeController.java create mode 100644 apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java create mode 100644 apps/challenge-user-service/server/src/main/java/org/openapitools/model/User.java create mode 100644 apps/challenge-user-service/server/src/main/java/org/openapitools/model/UserUpdateRequest.java create mode 100644 apps/challenge-user-service/server/src/main/resources/application.properties create mode 100644 apps/challenge-user-service/server/src/main/resources/openapi.yaml create mode 100644 apps/challenge-user-service/server/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/generate-server.sh b/apps/challenge-user-service/generate-server.sh new file mode 100755 index 0000000000..64cf773c99 --- /dev/null +++ b/apps/challenge-user-service/generate-server.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +openapi-generator-cli generate \ + -g spring \ + -o server \ + -i docs/openapi.yaml \ No newline at end of file diff --git a/openapitools.json b/apps/challenge-user-service/openapitools.json similarity index 100% rename from openapitools.json rename to apps/challenge-user-service/openapitools.json diff --git a/apps/challenge-user-service/server/.openapi-generator-ignore b/apps/challenge-user-service/server/.openapi-generator-ignore new file mode 100644 index 0000000000..7484ee590a --- /dev/null +++ b/apps/challenge-user-service/server/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/apps/challenge-user-service/server/.openapi-generator/FILES b/apps/challenge-user-service/server/.openapi-generator/FILES new file mode 100644 index 0000000000..4f81136c06 --- /dev/null +++ b/apps/challenge-user-service/server/.openapi-generator/FILES @@ -0,0 +1,15 @@ +.openapi-generator-ignore +README.md +pom.xml +src/main/java/org/openapitools/OpenApiGeneratorApplication.java +src/main/java/org/openapitools/RFC3339DateFormat.java +src/main/java/org/openapitools/api/ApiApi.java +src/main/java/org/openapitools/api/ApiApiController.java +src/main/java/org/openapitools/api/ApiUtil.java +src/main/java/org/openapitools/configuration/HomeController.java +src/main/java/org/openapitools/configuration/SpringDocConfiguration.java +src/main/java/org/openapitools/model/User.java +src/main/java/org/openapitools/model/UserUpdateRequest.java +src/main/resources/application.properties +src/main/resources/openapi.yaml +src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/server/.openapi-generator/VERSION b/apps/challenge-user-service/server/.openapi-generator/VERSION new file mode 100644 index 0000000000..358e78e607 --- /dev/null +++ b/apps/challenge-user-service/server/.openapi-generator/VERSION @@ -0,0 +1 @@ +6.1.0 \ No newline at end of file diff --git a/apps/challenge-user-service/server/README.md b/apps/challenge-user-service/server/README.md new file mode 100644 index 0000000000..6a7407b2a6 --- /dev/null +++ b/apps/challenge-user-service/server/README.md @@ -0,0 +1,21 @@ +# OpenAPI generated server + +Spring Boot Server + +## Overview +This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. +By using the [OpenAPI-Spec](https://openapis.org), you can easily generate a server stub. +This is an example of building a OpenAPI-enabled server in Java using the SpringBoot framework. + + +The underlying library integrating OpenAPI to Spring Boot is [springdoc](https://springdoc.org). +Springdoc will generate an OpenAPI v3 specification based on the generated Controller and Model classes. +The specification is available to download using the following url: +http://localhost:8083/v3/api-docs/ + +Start your server as a simple java application + +You can view the api documentation in swagger-ui by pointing to +http://localhost:8083/swagger-ui.html + +Change default port value in application.properties \ No newline at end of file diff --git a/apps/challenge-user-service/server/pom.xml b/apps/challenge-user-service/server/pom.xml new file mode 100644 index 0000000000..6ebfb6b83a --- /dev/null +++ b/apps/challenge-user-service/server/pom.xml @@ -0,0 +1,80 @@ + + 4.0.0 + org.openapitools + openapi-spring + jar + openapi-spring + v1.0 + + 1.8 + ${java.version} + ${java.version} + UTF-8 + 1.6.8 + 4.10.3 + + + org.springframework.boot + spring-boot-starter-parent + 2.7.0 + + + + src/main/java + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.data + spring-data-commons + + + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + org.openapitools + jackson-databind-nullable + 0.2.2 + + + + org.springframework.boot + spring-boot-starter-validation + + + com.fasterxml.jackson.core + jackson-databind + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java b/apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java new file mode 100644 index 0000000000..f62fd6d917 --- /dev/null +++ b/apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java @@ -0,0 +1,23 @@ +package org.openapitools; + +import com.fasterxml.jackson.databind.Module; +import org.openapitools.jackson.nullable.JsonNullableModule; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = {"org.openapitools", "org.openapitools.api" , "org.openapitools.configuration"}) +public class OpenApiGeneratorApplication { + + public static void main(String[] args) { + SpringApplication.run(OpenApiGeneratorApplication.class, args); + } + + @Bean + public Module jsonNullableModule() { + return new JsonNullableModule(); + } + +} \ No newline at end of file diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/RFC3339DateFormat.java b/apps/challenge-user-service/server/src/main/java/org/openapitools/RFC3339DateFormat.java new file mode 100644 index 0000000000..bcd3936d8b --- /dev/null +++ b/apps/challenge-user-service/server/src/main/java/org/openapitools/RFC3339DateFormat.java @@ -0,0 +1,38 @@ +package org.openapitools; + +import com.fasterxml.jackson.databind.util.StdDateFormat; + +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +public class RFC3339DateFormat extends DateFormat { + private static final long serialVersionUID = 1L; + private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC"); + + private final StdDateFormat fmt = new StdDateFormat() + .withTimeZone(TIMEZONE_Z) + .withColonInTimeZone(true); + + public RFC3339DateFormat() { + this.calendar = new GregorianCalendar(); + } + + @Override + public Date parse(String source, ParsePosition pos) { + return fmt.parse(source, pos); + } + + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + return fmt.format(date, toAppendTo, fieldPosition); + } + + @Override + public Object clone() { + return this; + } +} \ No newline at end of file diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApi.java b/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApi.java new file mode 100644 index 0000000000..10af272522 --- /dev/null +++ b/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApi.java @@ -0,0 +1,198 @@ +/** + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (6.1.0). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +package org.openapitools.api; + +import org.openapitools.model.User; +import org.openapitools.model.UserUpdateRequest; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.Valid; +import javax.validation.constraints.*; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.annotation.Generated; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-14T23:46:16.887276700Z[Etc/UTC]") +@Validated +@Tag(name = "api", description = "the api API") +@RequestMapping("${openapi.user.base-path:}") +public interface ApiApi { + + default Optional getRequest() { + return Optional.empty(); + } + + /** + * POST /api/v1/users/register + * + * @param user (required) + * @return OK (status code 200) + */ + @Operation( + operationId = "createUser", + tags = { "user-controller" }, + responses = { + @ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = User.class)) + }) + } + ) + @RequestMapping( + method = RequestMethod.POST, + value = "/api/v1/users/register", + produces = { "*/*" }, + consumes = { "application/json" } + ) + default ResponseEntity createUser( + @Parameter(name = "User", description = "", required = true) @Valid @RequestBody User user + ) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + + + /** + * GET /api/v1/users/{id} + * + * @param id (required) + * @return OK (status code 200) + */ + @Operation( + operationId = "getUser", + tags = { "user-controller" }, + responses = { + @ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = User.class)) + }) + } + ) + @RequestMapping( + method = RequestMethod.GET, + value = "/api/v1/users/{id}", + produces = { "*/*" } + ) + default ResponseEntity getUser( + @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id + ) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + + + /** + * GET /api/v1/users/ + * + * @param page Zero-based page index (0..N) (optional, default to 0) + * @param size The size of the page to be returned (optional, default to 20) + * @param sort Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. (optional) + * @return OK (status code 200) + */ + @Operation( + operationId = "listUsers", + tags = { "user-controller" }, + responses = { + @ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = User.class)) + }) + } + ) + @RequestMapping( + method = RequestMethod.GET, + value = "/api/v1/users/", + produces = { "*/*" } + ) + default ResponseEntity> listUsers( + @Min(0) @Parameter(name = "page", description = "Zero-based page index (0..N)") @Valid @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @Min(1) @Parameter(name = "size", description = "The size of the page to be returned") @Valid @RequestParam(value = "size", required = false, defaultValue = "20") Integer size, + @Parameter(name = "sort", description = "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.") @Valid @RequestParam(value = "sort", required = false) List sort + ) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + + + /** + * PATCH /api/v1/users/{id} + * + * @param id (required) + * @param userUpdateRequest (required) + * @return OK (status code 200) + */ + @Operation( + operationId = "updateUser", + tags = { "user-controller" }, + responses = { + @ApiResponse(responseCode = "200", description = "OK", content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = User.class)) + }) + } + ) + @RequestMapping( + method = RequestMethod.PATCH, + value = "/api/v1/users/{id}", + produces = { "*/*" }, + consumes = { "application/json" } + ) + default ResponseEntity updateUser( + @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id, + @Parameter(name = "UserUpdateRequest", description = "", required = true) @Valid @RequestBody UserUpdateRequest userUpdateRequest + ) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + +} diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApiController.java b/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApiController.java new file mode 100644 index 0000000000..18c5a7b36a --- /dev/null +++ b/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApiController.java @@ -0,0 +1,46 @@ +package org.openapitools.api; + +import org.openapitools.model.User; +import org.openapitools.model.UserUpdateRequest; + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.context.request.NativeWebRequest; + +import javax.validation.constraints.*; +import javax.validation.Valid; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.annotation.Generated; + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-14T23:46:16.887276700Z[Etc/UTC]") +@Controller +public class ApiApiController implements ApiApi { + + private final NativeWebRequest request; + + @Autowired + public ApiApiController(NativeWebRequest request) { + this.request = request; + } + + @Override + public Optional getRequest() { + return Optional.ofNullable(request); + } + +} diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiUtil.java b/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiUtil.java new file mode 100644 index 0000000000..1245b1dd0c --- /dev/null +++ b/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiUtil.java @@ -0,0 +1,19 @@ +package org.openapitools.api; + +import org.springframework.web.context.request.NativeWebRequest; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ApiUtil { + public static void setExampleResponse(NativeWebRequest req, String contentType, String example) { + try { + HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class); + res.setCharacterEncoding("UTF-8"); + res.addHeader("Content-Type", contentType); + res.getWriter().print(example); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/HomeController.java b/apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/HomeController.java new file mode 100644 index 0000000000..9aa29284ab --- /dev/null +++ b/apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/HomeController.java @@ -0,0 +1,20 @@ +package org.openapitools.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * Home redirection to OpenAPI api documentation + */ +@Controller +public class HomeController { + + @RequestMapping("/") + public String index() { + return "redirect:swagger-ui.html"; + } + +} \ No newline at end of file diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java b/apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java new file mode 100644 index 0000000000..e1540e920a --- /dev/null +++ b/apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java @@ -0,0 +1,38 @@ +package org.openapitools.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.security.SecurityScheme; + +@Configuration +public class SpringDocConfiguration { + + @Bean + OpenAPI apiInfo() { + return new OpenAPI() + .info( + new Info() + .title("User API") + .description("This is the User Service of the Challenge Registry.") + .termsOfService("TOC") + .contact( + new Contact() + .name("This is the User ") + .url("https://challenge-registry.org") + ) + .license( + new License() + .name("Apache 2.0") + .url("https://github.com/Sage-Bionetworks/challenge-registry/blob/main/LICENSE.txt") + ) + .version("v1.0") + ) + ; + } +} \ No newline at end of file diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/model/User.java b/apps/challenge-user-service/server/src/main/java/org/openapitools/model/User.java new file mode 100644 index 0000000000..427c801530 --- /dev/null +++ b/apps/challenge-user-service/server/src/main/java/org/openapitools/model/User.java @@ -0,0 +1,243 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; + + +import java.util.*; +import javax.annotation.Generated; + +/** + * User + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-14T23:46:16.887276700Z[Etc/UTC]") +public class User { + + @JsonProperty("id") + private Long id; + + @JsonProperty("username") + private String username; + + @JsonProperty("email") + private String email; + + @JsonProperty("password") + private String password; + + @JsonProperty("authId") + private String authId; + + /** + * Gets or Sets status + */ + public enum StatusEnum { + PENDING("PENDING"), + + APPROVED("APPROVED"), + + DISABLED("DISABLED"), + + BLACKLIST("BLACKLIST"); + + private String value; + + StatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static StatusEnum fromValue(String value) { + for (StatusEnum b : StatusEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + @JsonProperty("status") + private StatusEnum status; + + public User id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", required = false) + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public User username(String username) { + this.username = username; + return this; + } + + /** + * Get username + * @return username + */ + + @Schema(name = "username", required = false) + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public User email(String email) { + this.email = email; + return this; + } + + /** + * Get email + * @return email + */ + + @Schema(name = "email", required = false) + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public User password(String password) { + this.password = password; + return this; + } + + /** + * Get password + * @return password + */ + + @Schema(name = "password", required = false) + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public User authId(String authId) { + this.authId = authId; + return this; + } + + /** + * Get authId + * @return authId + */ + + @Schema(name = "authId", required = false) + public String getAuthId() { + return authId; + } + + public void setAuthId(String authId) { + this.authId = authId; + } + + public User status(StatusEnum status) { + this.status = status; + return this; + } + + /** + * Get status + * @return status + */ + + @Schema(name = "status", required = false) + public StatusEnum getStatus() { + return status; + } + + public void setStatus(StatusEnum status) { + this.status = status; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + User user = (User) o; + return Objects.equals(this.id, user.id) && + Objects.equals(this.username, user.username) && + Objects.equals(this.email, user.email) && + Objects.equals(this.password, user.password) && + Objects.equals(this.authId, user.authId) && + Objects.equals(this.status, user.status); + } + + @Override + public int hashCode() { + return Objects.hash(id, username, email, password, authId, status); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class User {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" username: ").append(toIndentedString(username)).append("\n"); + sb.append(" email: ").append(toIndentedString(email)).append("\n"); + sb.append(" password: ").append(toIndentedString(password)).append("\n"); + sb.append(" authId: ").append(toIndentedString(authId)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/model/UserUpdateRequest.java b/apps/challenge-user-service/server/src/main/java/org/openapitools/model/UserUpdateRequest.java new file mode 100644 index 0000000000..1cae2a1953 --- /dev/null +++ b/apps/challenge-user-service/server/src/main/java/org/openapitools/model/UserUpdateRequest.java @@ -0,0 +1,123 @@ +package org.openapitools.model; + +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; + + +import java.util.*; +import javax.annotation.Generated; + +/** + * UserUpdateRequest + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-14T23:46:16.887276700Z[Etc/UTC]") +public class UserUpdateRequest { + + /** + * Gets or Sets status + */ + public enum StatusEnum { + PENDING("PENDING"), + + APPROVED("APPROVED"), + + DISABLED("DISABLED"), + + BLACKLIST("BLACKLIST"); + + private String value; + + StatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static StatusEnum fromValue(String value) { + for (StatusEnum b : StatusEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + @JsonProperty("status") + private StatusEnum status; + + public UserUpdateRequest status(StatusEnum status) { + this.status = status; + return this; + } + + /** + * Get status + * @return status + */ + + @Schema(name = "status", required = false) + public StatusEnum getStatus() { + return status; + } + + public void setStatus(StatusEnum status) { + this.status = status; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UserUpdateRequest userUpdateRequest = (UserUpdateRequest) o; + return Objects.equals(this.status, userUpdateRequest.status); + } + + @Override + public int hashCode() { + return Objects.hash(status); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UserUpdateRequest {\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/apps/challenge-user-service/server/src/main/resources/application.properties b/apps/challenge-user-service/server/src/main/resources/application.properties new file mode 100644 index 0000000000..3bbbe2c05e --- /dev/null +++ b/apps/challenge-user-service/server/src/main/resources/application.properties @@ -0,0 +1,3 @@ +server.port=8083 +spring.jackson.date-format=org.openapitools.RFC3339DateFormat +spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false diff --git a/apps/challenge-user-service/server/src/main/resources/openapi.yaml b/apps/challenge-user-service/server/src/main/resources/openapi.yaml new file mode 100644 index 0000000000..f039156564 --- /dev/null +++ b/apps/challenge-user-service/server/src/main/resources/openapi.yaml @@ -0,0 +1,183 @@ +openapi: 3.0.1 +info: + contact: + name: 'This is the User ' + url: https://challenge-registry.org + description: This is the User Service of the Challenge Registry. + license: + name: Apache 2.0 + url: https://github.com/Sage-Bionetworks/challenge-registry/blob/main/LICENSE.txt + termsOfService: TOC + title: User API + version: v1.0 +servers: +- description: Generated server url + url: http://localhost:8083 +paths: + /api/v1/users/register: + post: + operationId: createUser + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' + required: true + responses: + "200": + content: + '*/*': + schema: + $ref: '#/components/schemas/User' + description: OK + tags: + - user-controller + x-content-type: application/json + x-accepts: '*/*' + x-tags: + - tag: user-controller + /api/v1/users/{id}: + get: + operationId: getUser + parameters: + - explode: false + in: path + name: id + required: true + schema: + format: int64 + type: integer + style: simple + responses: + "200": + content: + '*/*': + schema: + $ref: '#/components/schemas/User' + description: OK + tags: + - user-controller + x-accepts: '*/*' + x-tags: + - tag: user-controller + patch: + operationId: updateUser + parameters: + - explode: false + in: path + name: id + required: true + schema: + format: int64 + type: integer + style: simple + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserUpdateRequest' + required: true + responses: + "200": + content: + '*/*': + schema: + $ref: '#/components/schemas/User' + description: OK + tags: + - user-controller + x-content-type: application/json + x-accepts: '*/*' + x-tags: + - tag: user-controller + /api/v1/users/: + get: + operationId: listUsers + parameters: + - description: Zero-based page index (0..N) + explode: true + in: query + name: page + required: false + schema: + default: 0 + minimum: 0 + type: integer + style: form + - description: The size of the page to be returned + explode: true + in: query + name: size + required: false + schema: + default: 20 + minimum: 1 + type: integer + style: form + - description: "Sorting criteria in the format: property,(asc|desc). Default\ + \ sort order is ascending. Multiple sort criteria are supported." + explode: true + in: query + name: sort + required: false + schema: + items: + type: string + type: array + style: form + responses: + "200": + content: + '*/*': + schema: + items: + $ref: '#/components/schemas/User' + type: array + description: OK + tags: + - user-controller + x-accepts: '*/*' + x-tags: + - tag: user-controller +components: + schemas: + User: + example: + password: password + id: 0 + email: email + authId: authId + username: username + status: PENDING + properties: + id: + format: int64 + type: integer + username: + type: string + email: + type: string + password: + type: string + authId: + type: string + status: + enum: + - PENDING + - APPROVED + - DISABLED + - BLACKLIST + type: string + type: object + UserUpdateRequest: + example: + status: PENDING + properties: + status: + enum: + - PENDING + - APPROVED + - DISABLED + - BLACKLIST + type: string + type: object diff --git a/apps/challenge-user-service/server/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java b/apps/challenge-user-service/server/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java new file mode 100644 index 0000000000..3681f67e77 --- /dev/null +++ b/apps/challenge-user-service/server/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java @@ -0,0 +1,13 @@ +package org.openapitools; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class OpenApiGeneratorApplicationTests { + + @Test + void contextLoads() { + } + +} \ No newline at end of file From cf8bfcbd6dfc23943cde8e936d3c47831f1c37a7 Mon Sep 17 00:00:00 2001 From: tschaffter Date: Thu, 15 Sep 2022 17:13:34 +0000 Subject: [PATCH 04/62] Add generator configuration to openapitools.json --- .../challenge-user-service/generate-server.sh | 6 - apps/challenge-user-service/openapi.yaml | 150 ++++++++++++++++++ apps/challenge-user-service/openapitools.json | 11 +- 3 files changed, 159 insertions(+), 8 deletions(-) delete mode 100755 apps/challenge-user-service/generate-server.sh create mode 100644 apps/challenge-user-service/openapi.yaml diff --git a/apps/challenge-user-service/generate-server.sh b/apps/challenge-user-service/generate-server.sh deleted file mode 100755 index 64cf773c99..0000000000 --- a/apps/challenge-user-service/generate-server.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -openapi-generator-cli generate \ - -g spring \ - -o server \ - -i docs/openapi.yaml \ No newline at end of file diff --git a/apps/challenge-user-service/openapi.yaml b/apps/challenge-user-service/openapi.yaml new file mode 100644 index 0000000000..c1a643d8e9 --- /dev/null +++ b/apps/challenge-user-service/openapi.yaml @@ -0,0 +1,150 @@ +openapi: 3.0.1 +info: + title: User API + description: This is the User Service of the Challenge Registry. + termsOfService: TOC + contact: + name: 'This is the User ' + url: https://challenge-registry.org + license: + name: Apache 2.0 + url: https://github.com/Sage-Bionetworks/challenge-registry/blob/main/LICENSE.txt + version: v1.0 +servers: +- url: http://localhost:8083 + description: Generated server url +paths: + /api/v1/users/register: + post: + tags: + - user-controller + operationId: createUser + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/User' + required: true + responses: + "200": + description: OK + content: + '*/*': + schema: + $ref: '#/components/schemas/User' + /api/v1/users/{id}: + get: + tags: + - user-controller + operationId: getUser + parameters: + - name: id + in: path + required: true + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + '*/*': + schema: + $ref: '#/components/schemas/User' + patch: + tags: + - user-controller + operationId: updateUser + parameters: + - name: id + in: path + required: true + schema: + type: integer + format: int64 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserUpdateRequest' + required: true + responses: + "200": + description: OK + content: + '*/*': + schema: + $ref: '#/components/schemas/User' + /api/v1/users/: + get: + tags: + - user-controller + operationId: listUsers + parameters: + - name: page + in: query + description: Zero-based page index (0..N) + required: false + schema: + minimum: 0 + type: integer + default: 0 + - name: size + in: query + description: The size of the page to be returned + required: false + schema: + minimum: 1 + type: integer + default: 20 + - name: sort + in: query + description: "Sorting criteria in the format: property,(asc|desc). Default\ + \ sort order is ascending. Multiple sort criteria are supported." + required: false + schema: + type: array + items: + type: string + responses: + "200": + description: OK + content: + '*/*': + schema: + type: array + items: + $ref: '#/components/schemas/User' +components: + schemas: + User: + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + email: + type: string + password: + type: string + authId: + type: string + status: + type: string + enum: + - PENDING + - APPROVED + - DISABLED + - BLACKLIST + UserUpdateRequest: + type: object + properties: + status: + type: string + enum: + - PENDING + - APPROVED + - DISABLED + - BLACKLIST diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index 712bf341be..6a02b8699a 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -1,7 +1,14 @@ { - "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "$schema": "../../node_modules/@openapitools/openapi-generator-cli/config.schema.json", "spaces": 2, "generator-cli": { - "version": "6.1.0" + "version": "6.1.0", + "generators": { + "challenge-user-service": { + "generatorName": "spring", + "output": "server", + "inputSpec": "openapi.yaml" + } + } } } From 93db4843b33631b33a0496f497372970c53d421a Mon Sep 17 00:00:00 2001 From: tschaffter Date: Thu, 15 Sep 2022 20:42:29 +0000 Subject: [PATCH 05/62] Enable delegate pattern --- apps/challenge-user-service/openapitools.json | 8 +- .../server/.openapi-generator/FILES | 11 +- .../OpenApiGeneratorApplication.java | 2 +- .../challenge}/api/ApiApi.java | 64 ++-------- .../challenge}/api/ApiApiController.java | 20 ++- .../challenge/api/ApiApiDelegate.java | 117 ++++++++++++++++++ .../challenge}/api/ApiUtil.java | 2 +- .../challenge/model/dto}/User.java | 4 +- .../model/dto}/UserUpdateRequest.java | 4 +- 9 files changed, 155 insertions(+), 77 deletions(-) rename apps/challenge-user-service/server/src/main/java/org/{openapitools => sagebionetworks/challenge}/api/ApiApi.java (63%) rename apps/challenge-user-service/server/src/main/java/org/{openapitools => sagebionetworks/challenge}/api/ApiApiController.java (68%) create mode 100644 apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java rename apps/challenge-user-service/server/src/main/java/org/{openapitools => sagebionetworks/challenge}/api/ApiUtil.java (93%) rename apps/challenge-user-service/server/src/main/java/org/{openapitools/model => sagebionetworks/challenge/model/dto}/User.java (97%) rename apps/challenge-user-service/server/src/main/java/org/{openapitools/model => sagebionetworks/challenge/model/dto}/UserUpdateRequest.java (96%) diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index 6a02b8699a..6a1938d46b 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -7,7 +7,13 @@ "challenge-user-service": { "generatorName": "spring", "output": "server", - "inputSpec": "openapi.yaml" + "inputSpec": "openapi.yaml", + "apiPackage": "org.sagebionetworks.challenge.api", + "modelPackage": "org.sagebionetworks.challenge.model.dto", + "templateDir": "templates", + "additionalProperties": { + "delegatePattern": true + } } } } diff --git a/apps/challenge-user-service/server/.openapi-generator/FILES b/apps/challenge-user-service/server/.openapi-generator/FILES index 4f81136c06..80e486cd56 100644 --- a/apps/challenge-user-service/server/.openapi-generator/FILES +++ b/apps/challenge-user-service/server/.openapi-generator/FILES @@ -3,13 +3,14 @@ README.md pom.xml src/main/java/org/openapitools/OpenApiGeneratorApplication.java src/main/java/org/openapitools/RFC3339DateFormat.java -src/main/java/org/openapitools/api/ApiApi.java -src/main/java/org/openapitools/api/ApiApiController.java -src/main/java/org/openapitools/api/ApiUtil.java src/main/java/org/openapitools/configuration/HomeController.java src/main/java/org/openapitools/configuration/SpringDocConfiguration.java -src/main/java/org/openapitools/model/User.java -src/main/java/org/openapitools/model/UserUpdateRequest.java +src/main/java/org/sagebionetworks/challenge/api/ApiApi.java +src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java +src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java +src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java +src/main/java/org/sagebionetworks/challenge/model/dto/User.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java src/main/resources/application.properties src/main/resources/openapi.yaml src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java b/apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java index f62fd6d917..27f923fd92 100644 --- a/apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java +++ b/apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java @@ -8,7 +8,7 @@ import org.springframework.context.annotation.ComponentScan; @SpringBootApplication -@ComponentScan(basePackages = {"org.openapitools", "org.openapitools.api" , "org.openapitools.configuration"}) +@ComponentScan(basePackages = {"org.openapitools", "org.sagebionetworks.challenge.api" , "org.openapitools.configuration"}) public class OpenApiGeneratorApplication { public static void main(String[] args) { diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApi.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApi.java similarity index 63% rename from apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApi.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApi.java index 10af272522..3ec7e32676 100644 --- a/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApi.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApi.java @@ -3,10 +3,10 @@ * https://openapi-generator.tech * Do not edit the class manually. */ -package org.openapitools.api; +package org.sagebionetworks.challenge.api; -import org.openapitools.model.User; -import org.openapitools.model.UserUpdateRequest; +import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; @@ -15,29 +15,25 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.multipart.MultipartFile; import javax.validation.Valid; import javax.validation.constraints.*; import java.util.List; import java.util.Map; -import java.util.Optional; import javax.annotation.Generated; -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-14T23:46:16.887276700Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T17:33:42.298982800Z[Etc/UTC]") @Validated @Tag(name = "api", description = "the api API") @RequestMapping("${openapi.user.base-path:}") public interface ApiApi { - default Optional getRequest() { - return Optional.empty(); + default ApiApiDelegate getDelegate() { + return new ApiApiDelegate() {}; } /** @@ -64,17 +60,7 @@ default Optional getRequest() { default ResponseEntity createUser( @Parameter(name = "User", description = "", required = true) @Valid @RequestBody User user ) { - getRequest().ifPresent(request -> { - for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { - if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { - String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); - break; - } - } - }); - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - + return getDelegate().createUser(user); } @@ -101,17 +87,7 @@ default ResponseEntity createUser( default ResponseEntity getUser( @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id ) { - getRequest().ifPresent(request -> { - for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { - if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { - String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); - break; - } - } - }); - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - + return getDelegate().getUser(id); } @@ -142,17 +118,7 @@ default ResponseEntity> listUsers( @Min(1) @Parameter(name = "size", description = "The size of the page to be returned") @Valid @RequestParam(value = "size", required = false, defaultValue = "20") Integer size, @Parameter(name = "sort", description = "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.") @Valid @RequestParam(value = "sort", required = false) List sort ) { - getRequest().ifPresent(request -> { - for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { - if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { - String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); - break; - } - } - }); - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - + return getDelegate().listUsers(page, size, sort); } @@ -182,17 +148,7 @@ default ResponseEntity updateUser( @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id, @Parameter(name = "UserUpdateRequest", description = "", required = true) @Valid @RequestBody UserUpdateRequest userUpdateRequest ) { - getRequest().ifPresent(request -> { - for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { - if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { - String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); - break; - } - } - }); - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - + return getDelegate().updateUser(id, userUpdateRequest); } } diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApiController.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java similarity index 68% rename from apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApiController.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java index 18c5a7b36a..4b739e1047 100644 --- a/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiApiController.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java @@ -1,7 +1,7 @@ -package org.openapitools.api; +package org.sagebionetworks.challenge.api; -import org.openapitools.model.User; -import org.openapitools.model.UserUpdateRequest; +import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; import org.springframework.beans.factory.annotation.Autowired; @@ -17,7 +17,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.context.request.NativeWebRequest; import javax.validation.constraints.*; import javax.validation.Valid; @@ -27,20 +26,19 @@ import java.util.Optional; import javax.annotation.Generated; -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-14T23:46:16.887276700Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T17:33:42.298982800Z[Etc/UTC]") @Controller public class ApiApiController implements ApiApi { - private final NativeWebRequest request; + private final ApiApiDelegate delegate; - @Autowired - public ApiApiController(NativeWebRequest request) { - this.request = request; + public ApiApiController(@Autowired(required = false) ApiApiDelegate delegate) { + this.delegate = Optional.ofNullable(delegate).orElse(new ApiApiDelegate() {}); } @Override - public Optional getRequest() { - return Optional.ofNullable(request); + public ApiApiDelegate getDelegate() { + return delegate; } } diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java new file mode 100644 index 0000000000..102bcd77c6 --- /dev/null +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java @@ -0,0 +1,117 @@ +package org.sagebionetworks.challenge.api; + +import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.annotation.Generated; + +/** + * A delegate to be called by the {@link ApiApiController}}. + * Implement this interface with a {@link org.springframework.stereotype.Service} annotated class. + */ +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T17:33:42.298982800Z[Etc/UTC]") +public interface ApiApiDelegate { + + default Optional getRequest() { + return Optional.empty(); + } + + /** + * POST /api/v1/users/register + * + * @param user (required) + * @return OK (status code 200) + * @see ApiApi#createUser + */ + default ResponseEntity createUser(User user) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + + /** + * GET /api/v1/users/{id} + * + * @param id (required) + * @return OK (status code 200) + * @see ApiApi#getUser + */ + default ResponseEntity getUser(Long id) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + + /** + * GET /api/v1/users/ + * + * @param page Zero-based page index (0..N) (optional, default to 0) + * @param size The size of the page to be returned (optional, default to 20) + * @param sort Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. (optional) + * @return OK (status code 200) + * @see ApiApi#listUsers + */ + default ResponseEntity> listUsers(Integer page, + Integer size, + List sort) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + + /** + * PATCH /api/v1/users/{id} + * + * @param id (required) + * @param userUpdateRequest (required) + * @return OK (status code 200) + * @see ApiApi#updateUser + */ + default ResponseEntity updateUser(Long id, + UserUpdateRequest userUpdateRequest) { + getRequest().ifPresent(request -> { + for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; + } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + + } + +} diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiUtil.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java similarity index 93% rename from apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiUtil.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java index 1245b1dd0c..de8997fba3 100644 --- a/apps/challenge-user-service/server/src/main/java/org/openapitools/api/ApiUtil.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java @@ -1,4 +1,4 @@ -package org.openapitools.api; +package org.sagebionetworks.challenge.api; import org.springframework.web.context.request.NativeWebRequest; diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/model/User.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java similarity index 97% rename from apps/challenge-user-service/server/src/main/java/org/openapitools/model/User.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java index 427c801530..9a2d619ac1 100644 --- a/apps/challenge-user-service/server/src/main/java/org/openapitools/model/User.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java @@ -1,4 +1,4 @@ -package org.openapitools.model; +package org.sagebionetworks.challenge.model.dto; import java.net.URI; import java.util.Objects; @@ -19,7 +19,7 @@ * User */ -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-14T23:46:16.887276700Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T17:33:42.298982800Z[Etc/UTC]") public class User { @JsonProperty("id") diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/model/UserUpdateRequest.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java similarity index 96% rename from apps/challenge-user-service/server/src/main/java/org/openapitools/model/UserUpdateRequest.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java index 1cae2a1953..8af7c1ca35 100644 --- a/apps/challenge-user-service/server/src/main/java/org/openapitools/model/UserUpdateRequest.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java @@ -1,4 +1,4 @@ -package org.openapitools.model; +package org.sagebionetworks.challenge.model.dto; import java.net.URI; import java.util.Objects; @@ -19,7 +19,7 @@ * UserUpdateRequest */ -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-14T23:46:16.887276700Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T17:33:42.298982800Z[Etc/UTC]") public class UserUpdateRequest { /** From cc6a222479ae9280f6a97bc24958867aa2ff3b9e Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 15 Sep 2022 22:56:04 +0000 Subject: [PATCH 06/62] Set base and config package name --- apps/challenge-user-service/openapitools.json | 6 ++++-- .../server/.openapi-generator/FILES | 10 +++++----- .../challenge}/OpenApiGeneratorApplication.java | 4 ++-- .../challenge}/RFC3339DateFormat.java | 2 +- .../java/org/sagebionetworks/challenge/api/ApiApi.java | 2 +- .../challenge/api/ApiApiController.java | 2 +- .../sagebionetworks/challenge/api/ApiApiDelegate.java | 2 +- .../challenge}/configuration/HomeController.java | 2 +- .../configuration/SpringDocConfiguration.java | 2 +- .../org/sagebionetworks/challenge/model/dto/User.java | 2 +- .../challenge/model/dto/UserUpdateRequest.java | 2 +- .../server/src/main/resources/application.properties | 2 +- .../challenge}/OpenApiGeneratorApplicationTests.java | 2 +- 13 files changed, 21 insertions(+), 19 deletions(-) rename apps/challenge-user-service/server/src/main/java/org/{openapitools => sagebionetworks/challenge}/OpenApiGeneratorApplication.java (77%) rename apps/challenge-user-service/server/src/main/java/org/{openapitools => sagebionetworks/challenge}/RFC3339DateFormat.java (96%) rename apps/challenge-user-service/server/src/main/java/org/{openapitools => sagebionetworks/challenge}/configuration/HomeController.java (90%) rename apps/challenge-user-service/server/src/main/java/org/{openapitools => sagebionetworks/challenge}/configuration/SpringDocConfiguration.java (96%) rename apps/challenge-user-service/server/src/test/java/org/{openapitools => sagebionetworks/challenge}/OpenApiGeneratorApplicationTests.java (83%) diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index 6a1938d46b..37d5204295 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -8,10 +8,12 @@ "generatorName": "spring", "output": "server", "inputSpec": "openapi.yaml", - "apiPackage": "org.sagebionetworks.challenge.api", - "modelPackage": "org.sagebionetworks.challenge.model.dto", "templateDir": "templates", "additionalProperties": { + "basePackage": "org.sagebionetworks.challenge", + "apiPackage": "org.sagebionetworks.challenge.api", + "modelPackage": "org.sagebionetworks.challenge.model.dto", + "configPackage": "org.sagebionetworks.challenge.configuration", "delegatePattern": true } } diff --git a/apps/challenge-user-service/server/.openapi-generator/FILES b/apps/challenge-user-service/server/.openapi-generator/FILES index 80e486cd56..59f3f6eceb 100644 --- a/apps/challenge-user-service/server/.openapi-generator/FILES +++ b/apps/challenge-user-service/server/.openapi-generator/FILES @@ -1,16 +1,16 @@ .openapi-generator-ignore README.md pom.xml -src/main/java/org/openapitools/OpenApiGeneratorApplication.java -src/main/java/org/openapitools/RFC3339DateFormat.java -src/main/java/org/openapitools/configuration/HomeController.java -src/main/java/org/openapitools/configuration/SpringDocConfiguration.java +src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java +src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java src/main/java/org/sagebionetworks/challenge/api/ApiApi.java src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java +src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java +src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java src/main/java/org/sagebionetworks/challenge/model/dto/User.java src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java src/main/resources/application.properties src/main/resources/openapi.yaml -src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java +src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java similarity index 77% rename from apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java index 27f923fd92..1eddb57b27 100644 --- a/apps/challenge-user-service/server/src/main/java/org/openapitools/OpenApiGeneratorApplication.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java @@ -1,4 +1,4 @@ -package org.openapitools; +package org.sagebionetworks.challenge; import com.fasterxml.jackson.databind.Module; import org.openapitools.jackson.nullable.JsonNullableModule; @@ -8,7 +8,7 @@ import org.springframework.context.annotation.ComponentScan; @SpringBootApplication -@ComponentScan(basePackages = {"org.openapitools", "org.sagebionetworks.challenge.api" , "org.openapitools.configuration"}) +@ComponentScan(basePackages = {"org.sagebionetworks.challenge", "org.sagebionetworks.challenge.api" , "org.sagebionetworks.challenge.configuration"}) public class OpenApiGeneratorApplication { public static void main(String[] args) { diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/RFC3339DateFormat.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java similarity index 96% rename from apps/challenge-user-service/server/src/main/java/org/openapitools/RFC3339DateFormat.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java index bcd3936d8b..f7ae51cd36 100644 --- a/apps/challenge-user-service/server/src/main/java/org/openapitools/RFC3339DateFormat.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java @@ -1,4 +1,4 @@ -package org.openapitools; +package org.sagebionetworks.challenge; import com.fasterxml.jackson.databind.util.StdDateFormat; diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApi.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApi.java index 3ec7e32676..a5d8e8f796 100644 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApi.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApi.java @@ -26,7 +26,7 @@ import java.util.Map; import javax.annotation.Generated; -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T17:33:42.298982800Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T22:55:24.066910493Z[Etc/UTC]") @Validated @Tag(name = "api", description = "the api API") @RequestMapping("${openapi.user.base-path:}") diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java index 4b739e1047..76aabe3286 100644 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java @@ -26,7 +26,7 @@ import java.util.Optional; import javax.annotation.Generated; -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T17:33:42.298982800Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T22:55:24.066910493Z[Etc/UTC]") @Controller public class ApiApiController implements ApiApi { diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java index 102bcd77c6..6865a3d9b8 100644 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java @@ -17,7 +17,7 @@ * A delegate to be called by the {@link ApiApiController}}. * Implement this interface with a {@link org.springframework.stereotype.Service} annotated class. */ -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T17:33:42.298982800Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T22:55:24.066910493Z[Etc/UTC]") public interface ApiApiDelegate { default Optional getRequest() { diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/HomeController.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java similarity index 90% rename from apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/HomeController.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java index 9aa29284ab..e581cfb2ca 100644 --- a/apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/HomeController.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java @@ -1,4 +1,4 @@ -package org.openapitools.configuration; +package org.sagebionetworks.challenge.configuration; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Controller; diff --git a/apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java similarity index 96% rename from apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java index e1540e920a..1af2712112 100644 --- a/apps/challenge-user-service/server/src/main/java/org/openapitools/configuration/SpringDocConfiguration.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java @@ -1,4 +1,4 @@ -package org.openapitools.configuration; +package org.sagebionetworks.challenge.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java index 9a2d619ac1..3342ed94b1 100644 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java @@ -19,7 +19,7 @@ * User */ -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T17:33:42.298982800Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T22:55:24.066910493Z[Etc/UTC]") public class User { @JsonProperty("id") diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java index 8af7c1ca35..4f2bfd9167 100644 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java @@ -19,7 +19,7 @@ * UserUpdateRequest */ -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T17:33:42.298982800Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T22:55:24.066910493Z[Etc/UTC]") public class UserUpdateRequest { /** diff --git a/apps/challenge-user-service/server/src/main/resources/application.properties b/apps/challenge-user-service/server/src/main/resources/application.properties index 3bbbe2c05e..2dca10ed5c 100644 --- a/apps/challenge-user-service/server/src/main/resources/application.properties +++ b/apps/challenge-user-service/server/src/main/resources/application.properties @@ -1,3 +1,3 @@ server.port=8083 -spring.jackson.date-format=org.openapitools.RFC3339DateFormat +spring.jackson.date-format=org.sagebionetworks.challenge.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false diff --git a/apps/challenge-user-service/server/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java b/apps/challenge-user-service/server/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java similarity index 83% rename from apps/challenge-user-service/server/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java rename to apps/challenge-user-service/server/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java index 3681f67e77..ff541d93f9 100644 --- a/apps/challenge-user-service/server/src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java +++ b/apps/challenge-user-service/server/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java @@ -1,4 +1,4 @@ -package org.openapitools; +package org.sagebionetworks.challenge; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; From f5a92566d3595a126f891c327882653e5bf25f1b Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 15 Sep 2022 23:11:28 +0000 Subject: [PATCH 07/62] Name generated files based on tag --- apps/challenge-user-service/openapitools.json | 4 +++- .../server/.openapi-generator/FILES | 6 +++--- .../api/{ApiApi.java => UserControllerApi.java} | 10 +++++----- ...oller.java => UserControllerApiController.java} | 12 ++++++------ ...elegate.java => UserControllerApiDelegate.java} | 14 +++++++------- .../sagebionetworks/challenge/model/dto/User.java | 2 +- .../challenge/model/dto/UserUpdateRequest.java | 2 +- 7 files changed, 26 insertions(+), 24 deletions(-) rename apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/{ApiApi.java => UserControllerApi.java} (96%) rename apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/{ApiApiController.java => UserControllerApiController.java} (79%) rename apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/{ApiApiDelegate.java => UserControllerApiDelegate.java} (93%) diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index 37d5204295..a2e15f3b07 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -14,7 +14,9 @@ "apiPackage": "org.sagebionetworks.challenge.api", "modelPackage": "org.sagebionetworks.challenge.model.dto", "configPackage": "org.sagebionetworks.challenge.configuration", - "delegatePattern": true + "delegatePattern": true, + "hideGenerationTimestamp": true, + "useTags": true } } } diff --git a/apps/challenge-user-service/server/.openapi-generator/FILES b/apps/challenge-user-service/server/.openapi-generator/FILES index 59f3f6eceb..9509212031 100644 --- a/apps/challenge-user-service/server/.openapi-generator/FILES +++ b/apps/challenge-user-service/server/.openapi-generator/FILES @@ -3,10 +3,10 @@ README.md pom.xml src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java -src/main/java/org/sagebionetworks/challenge/api/ApiApi.java -src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java -src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java +src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java +src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java +src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java src/main/java/org/sagebionetworks/challenge/model/dto/User.java diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApi.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java similarity index 96% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApi.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java index a5d8e8f796..758a2284f3 100644 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApi.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java @@ -26,14 +26,14 @@ import java.util.Map; import javax.annotation.Generated; -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T22:55:24.066910493Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @Validated -@Tag(name = "api", description = "the api API") +@Tag(name = "UserController", description = "the UserController API") @RequestMapping("${openapi.user.base-path:}") -public interface ApiApi { +public interface UserControllerApi { - default ApiApiDelegate getDelegate() { - return new ApiApiDelegate() {}; + default UserControllerApiDelegate getDelegate() { + return new UserControllerApiDelegate() {}; } /** diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java similarity index 79% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java index 76aabe3286..4e66358aea 100644 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiController.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java @@ -26,18 +26,18 @@ import java.util.Optional; import javax.annotation.Generated; -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T22:55:24.066910493Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @Controller -public class ApiApiController implements ApiApi { +public class UserControllerApiController implements UserControllerApi { - private final ApiApiDelegate delegate; + private final UserControllerApiDelegate delegate; - public ApiApiController(@Autowired(required = false) ApiApiDelegate delegate) { - this.delegate = Optional.ofNullable(delegate).orElse(new ApiApiDelegate() {}); + public UserControllerApiController(@Autowired(required = false) UserControllerApiDelegate delegate) { + this.delegate = Optional.ofNullable(delegate).orElse(new UserControllerApiDelegate() {}); } @Override - public ApiApiDelegate getDelegate() { + public UserControllerApiDelegate getDelegate() { return delegate; } diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java similarity index 93% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java rename to apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java index 6865a3d9b8..6d352b8944 100644 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiApiDelegate.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java @@ -14,11 +14,11 @@ import javax.annotation.Generated; /** - * A delegate to be called by the {@link ApiApiController}}. + * A delegate to be called by the {@link UserControllerApiController}}. * Implement this interface with a {@link org.springframework.stereotype.Service} annotated class. */ -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T22:55:24.066910493Z[Etc/UTC]") -public interface ApiApiDelegate { +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +public interface UserControllerApiDelegate { default Optional getRequest() { return Optional.empty(); @@ -29,7 +29,7 @@ default Optional getRequest() { * * @param user (required) * @return OK (status code 200) - * @see ApiApi#createUser + * @see UserControllerApi#createUser */ default ResponseEntity createUser(User user) { getRequest().ifPresent(request -> { @@ -50,7 +50,7 @@ default ResponseEntity createUser(User user) { * * @param id (required) * @return OK (status code 200) - * @see ApiApi#getUser + * @see UserControllerApi#getUser */ default ResponseEntity getUser(Long id) { getRequest().ifPresent(request -> { @@ -73,7 +73,7 @@ default ResponseEntity getUser(Long id) { * @param size The size of the page to be returned (optional, default to 20) * @param sort Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. (optional) * @return OK (status code 200) - * @see ApiApi#listUsers + * @see UserControllerApi#listUsers */ default ResponseEntity> listUsers(Integer page, Integer size, @@ -97,7 +97,7 @@ default ResponseEntity> listUsers(Integer page, * @param id (required) * @param userUpdateRequest (required) * @return OK (status code 200) - * @see ApiApi#updateUser + * @see UserControllerApi#updateUser */ default ResponseEntity updateUser(Long id, UserUpdateRequest userUpdateRequest) { diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java index 3342ed94b1..fae0cab306 100644 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java @@ -19,7 +19,7 @@ * User */ -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T22:55:24.066910493Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") public class User { @JsonProperty("id") diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java index 4f2bfd9167..a3e77bf978 100644 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +++ b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java @@ -19,7 +19,7 @@ * UserUpdateRequest */ -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-09-15T22:55:24.066910493Z[Etc/UTC]") +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") public class UserUpdateRequest { /** From 770012790fff08609de17ff70a764744508bea95 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 15 Sep 2022 23:56:20 +0000 Subject: [PATCH 08/62] Add template for application class --- .../templates/openapi2SpringBoot.mustache | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 apps/challenge-user-service/templates/openapi2SpringBoot.mustache diff --git a/apps/challenge-user-service/templates/openapi2SpringBoot.mustache b/apps/challenge-user-service/templates/openapi2SpringBoot.mustache new file mode 100644 index 0000000000..01725be2d2 --- /dev/null +++ b/apps/challenge-user-service/templates/openapi2SpringBoot.mustache @@ -0,0 +1,27 @@ +package {{basePackage}}; + +{{#openApiNullable}} +import com.fasterxml.jackson.databind.Module; +import org.openapitools.jackson.nullable.JsonNullableModule; +{{/openApiNullable}} +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = {"{{basePackage}}", "{{apiPackage}}" , "{{configPackage}}"}) +public class OpenApiGeneratorApplication { + + public static void main(String[] args) { + SpringApplication.run(OpenApiGeneratorApplication.class, args); + } + +{{#openApiNullable}} + @Bean + public Module jsonNullableModule() { + return new JsonNullableModule(); + } +{{/openApiNullable}} + +} \ No newline at end of file From bb04f2bf1042e927d24e40a8a58d5f16929f51c7 Mon Sep 17 00:00:00 2001 From: tschaffter Date: Fri, 16 Sep 2022 04:40:32 +0000 Subject: [PATCH 09/62] Start API stub with Gradle --- .gitignore | 1 + apps/challenge-user-service/build.gradle | 119 ++------- apps/challenge-user-service/build.gradle.old | 108 ++++++++ apps/challenge-user-service/pom.xml | 80 ++++++ .../challenge/model/dto/User.java | 243 ----------------- .../model/dto/UserUpdateRequest.java | 123 --------- .../ChallengeUserServiceApplicationTests.java | 0 .../UserRepositoryIntegrationTest.java | 0 .../integrationTest/resources/application.yml | 0 .../ChallengeUserServiceApplication.java | 0 .../CustomFeignClientConfiguration.java | 0 .../CustomFeignErrorDecoder.java | 0 .../configuration/KeycloakConfiguration.java | 0 .../configuration/KeycloakManager.java | 0 .../KeycloakManagerProperties.java | 0 .../configuration/OpenApiConfiguration.java | 0 .../configuration/SecurityConfiguration.java | 0 .../challenge/controller/UserController.java | 0 .../challenge/exception/GlobalErrorCode.java | 0 .../exception/InvalidEmailException.java | 0 .../exception/InvalidUserException.java | 0 .../UserAlreadyRegisteredException.java | 0 .../challenge/model/dto/User.java | 25 ++ .../challenge/model/dto/UserStatus.java | 0 .../model/dto/UserUpdateRequest.java | 8 + .../challenge/model/entity/UserEntity.java | 0 .../challenge/model/mapper/UserMapper.java | 0 .../model/repository/UserRepository.java | 0 .../model/rest/response/AccountResponse.java | 0 .../model/rest/response/UserResponse.java | 0 .../service/KeycloakUserService.java | 0 .../challenge/service/UserService.java | 0 .../service/rest/ChallengeCoreRestClient.java | 0 .../main/resources/application.yml | 0 ...V1.0.20210427174638__create_user_table.sql | 0 .../V1.0.20210427174721__temp_data.sql | 0 .../controller/UserControllerTest.java | 0 .../challenge/service/UserServiceTest.java | 0 .../test/resources/application.yml | 0 .../OpenApiGeneratorApplication.java | 0 .../challenge/RFC3339DateFormat.java | 0 .../challenge/api/ApiUtil.java | 0 .../challenge/api/UserControllerApi.java | 0 .../api/UserControllerApiController.java | 0 .../api/UserControllerApiDelegate.java | 0 .../configuration/HomeController.java | 0 .../configuration/SpringDocConfiguration.java | 0 .../challenge/model/dto/User.java | 248 ++++++++++++++++-- .../model/dto/UserUpdateRequest.java | 121 ++++++++- .../src/main/resources/application.properties | 0 .../src/main/resources/openapi.yaml | 0 .../OpenApiGeneratorApplicationTests.java | 0 52 files changed, 595 insertions(+), 481 deletions(-) create mode 100644 apps/challenge-user-service/build.gradle.old create mode 100644 apps/challenge-user-service/pom.xml delete mode 100644 apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java delete mode 100644 apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java rename apps/challenge-user-service/{src => src.old}/integrationTest/java/org/sagebionetworks/challenge/ChallengeUserServiceApplicationTests.java (100%) rename apps/challenge-user-service/{src => src.old}/integrationTest/java/org/sagebionetworks/challenge/model/repository/UserRepositoryIntegrationTest.java (100%) rename apps/challenge-user-service/{src => src.old}/integrationTest/resources/application.yml (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/configuration/CustomFeignClientConfiguration.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/configuration/CustomFeignErrorDecoder.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/configuration/KeycloakConfiguration.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/configuration/KeycloakManager.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/configuration/KeycloakManagerProperties.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/configuration/OpenApiConfiguration.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/configuration/SecurityConfiguration.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/controller/UserController.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/exception/GlobalErrorCode.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/exception/InvalidEmailException.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/exception/InvalidUserException.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/exception/UserAlreadyRegisteredException.java (100%) create mode 100644 apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/dto/User.java rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java (100%) create mode 100644 apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/model/repository/UserRepository.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/model/rest/response/AccountResponse.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/model/rest/response/UserResponse.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/service/KeycloakUserService.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/service/UserService.java (100%) rename apps/challenge-user-service/{src => src.old}/main/java/org/sagebionetworks/challenge/service/rest/ChallengeCoreRestClient.java (100%) rename apps/challenge-user-service/{src => src.old}/main/resources/application.yml (100%) rename apps/challenge-user-service/{src => src.old}/main/resources/db/migration/V1.0.20210427174638__create_user_table.sql (100%) rename apps/challenge-user-service/{src => src.old}/main/resources/db/migration/V1.0.20210427174721__temp_data.sql (100%) rename apps/challenge-user-service/{src => src.old}/test/java/org/sagebionetworks/challenge/controller/UserControllerTest.java (100%) rename apps/challenge-user-service/{src => src.old}/test/java/org/sagebionetworks/challenge/service/UserServiceTest.java (100%) rename apps/challenge-user-service/{src => src.old}/test/resources/application.yml (100%) rename apps/challenge-user-service/{server => }/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java (100%) rename apps/challenge-user-service/{server => }/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java (100%) rename apps/challenge-user-service/{server => }/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java (100%) rename apps/challenge-user-service/{server => }/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java (100%) rename apps/challenge-user-service/{server => }/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java (100%) rename apps/challenge-user-service/{server => }/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java (100%) rename apps/challenge-user-service/{server => }/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java (100%) rename apps/challenge-user-service/{server => }/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java (100%) rename apps/challenge-user-service/{server => }/src/main/resources/application.properties (100%) rename apps/challenge-user-service/{server => }/src/main/resources/openapi.yaml (100%) rename apps/challenge-user-service/{server => }/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java (100%) diff --git a/.gitignore b/.gitignore index 58a5f1beb2..45503ee52b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ !.yarn/plugins !.yarn/sdks !.yarn/versions +apps/challenge-user-service-2 # See http://help.github.com/ignore-files/ for more about ignoring files. .coveralls.yml diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index 1af6b09d23..09e770c5fb 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -1,108 +1,33 @@ plugins { - id 'io.spring.dependency-management' version '1.0.12.RELEASE' - id 'java' - id 'jvm-test-suite' - id 'org.springframework.boot' version '2.7.3' - id 'org.springdoc.openapi-gradle-plugin' version '1.4.0' + id 'java' + id 'org.springframework.boot' version '2.7.3' } -ext { - springVersion = '2.7.3' - springCloudVersion = '3.1.3' - keycloakVersion = '18.0.0' -} - -group = 'org.sagebionetworks.challenge' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '17' - repositories { - mavenCentral() - mavenLocal() -} - -testing { - suites { - test { - useJUnitJupiter() + mavenLocal() + maven { + url = uri('https://repo.maven.apache.org/maven2/') } - - integrationTest(JvmTestSuite) { - dependencies { - implementation project - } - sources { - java { - srcDirs = ['src/integrationTest/java'] - } - } - targets { - all { - testTask.configure { - shouldRunAfter(test) - } - } - } - } - } } dependencies { - annotationProcessor 'org.projectlombok:lombok:1.18.24' - compileOnly 'org.projectlombok:lombok:1.18.24' - implementation 'com.h2database:h2:2.1.214' - implementation 'org.flywaydb:flyway-core:9.3.0' - implementation 'org.flywaydb:flyway-mysql:9.3.0' - implementation "org.keycloak:keycloak-admin-client:${keycloakVersion}" - implementation "org.keycloak:keycloak-spring-boot-starter:${keycloakVersion}" - implementation 'org.sagebionetworks.challenge:challenge-util:0.0.1-SNAPSHOT' - implementation 'org.springdoc:springdoc-openapi-ui:1.6.11' - implementation "org.springframework.boot:spring-boot-devtools:${springVersion}" - implementation "org.springframework.boot:spring-boot-starter-actuator:${springVersion}" - implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springVersion}" - implementation "org.springframework.boot:spring-boot-starter-security:${springVersion}" - implementation "org.springframework.boot:spring-boot-starter-web:${springVersion}" - implementation "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:${springCloudVersion}" - implementation "org.springframework.cloud:spring-cloud-starter-openfeign:${springCloudVersion}" - integrationTestImplementation 'org.assertj:assertj-core:3.23.1' - integrationTestImplementation "org.springframework.boot:spring-boot-starter-test:${springVersion}" - runtimeOnly 'mysql:mysql-connector-java:8.0.30' - testImplementation 'org.assertj:assertj-core:3.23.1' - testImplementation "org.springframework.boot:spring-boot-starter-test:${springVersion}" -} - -configurations { - integrationTestImplementation.extendsFrom implementation - integrationTestRuntimeOnly.extendsFrom runtimeOnly -} - -// configure the integrationTest to run as part of a regular build -// tasks.named('check') { -// dependsOn(testing.suites.integrationTest) -// } - -test { - useJUnitPlatform() - - testLogging.showStandardStreams = true - - beforeTest { descriptor -> - logger.lifecycle("Running test: " + descriptor) - } - - failFast = true - - testLogging { - events("passed", "skipped", "failed") - } -} + implementation 'org.springframework.boot:spring-boot-starter-web:2.7.0' + implementation 'org.springframework.data:spring-data-commons:2.7.0' + implementation 'org.springdoc:springdoc-openapi-ui:1.6.8' + implementation 'com.google.code.findbugs:jsr305:3.0.2' + implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.3' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3' + implementation 'org.openapitools:jackson-databind-nullable:0.2.2' + implementation 'org.springframework.boot:spring-boot-starter-validation:2.7.0' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3' + testImplementation 'org.springframework.boot:spring-boot-starter-test:2.7.0' +} + +group = 'org.openapitools' +version = 'v1.0' +description = 'openapi-spring' +java.sourceCompatibility = JavaVersion.VERSION_1_8 tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' -} - -openApi { - apiDocsUrl.set("http://localhost:8083/api/v1/api-docs/openapi.json.yaml") - outputDir.set(file("docs")) - outputFileName.set("openapi.yaml") + options.encoding = 'UTF-8' } diff --git a/apps/challenge-user-service/build.gradle.old b/apps/challenge-user-service/build.gradle.old new file mode 100644 index 0000000000..1af6b09d23 --- /dev/null +++ b/apps/challenge-user-service/build.gradle.old @@ -0,0 +1,108 @@ +plugins { + id 'io.spring.dependency-management' version '1.0.12.RELEASE' + id 'java' + id 'jvm-test-suite' + id 'org.springframework.boot' version '2.7.3' + id 'org.springdoc.openapi-gradle-plugin' version '1.4.0' +} + +ext { + springVersion = '2.7.3' + springCloudVersion = '3.1.3' + keycloakVersion = '18.0.0' +} + +group = 'org.sagebionetworks.challenge' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '17' + +repositories { + mavenCentral() + mavenLocal() +} + +testing { + suites { + test { + useJUnitJupiter() + } + + integrationTest(JvmTestSuite) { + dependencies { + implementation project + } + sources { + java { + srcDirs = ['src/integrationTest/java'] + } + } + targets { + all { + testTask.configure { + shouldRunAfter(test) + } + } + } + } + } +} + +dependencies { + annotationProcessor 'org.projectlombok:lombok:1.18.24' + compileOnly 'org.projectlombok:lombok:1.18.24' + implementation 'com.h2database:h2:2.1.214' + implementation 'org.flywaydb:flyway-core:9.3.0' + implementation 'org.flywaydb:flyway-mysql:9.3.0' + implementation "org.keycloak:keycloak-admin-client:${keycloakVersion}" + implementation "org.keycloak:keycloak-spring-boot-starter:${keycloakVersion}" + implementation 'org.sagebionetworks.challenge:challenge-util:0.0.1-SNAPSHOT' + implementation 'org.springdoc:springdoc-openapi-ui:1.6.11' + implementation "org.springframework.boot:spring-boot-devtools:${springVersion}" + implementation "org.springframework.boot:spring-boot-starter-actuator:${springVersion}" + implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springVersion}" + implementation "org.springframework.boot:spring-boot-starter-security:${springVersion}" + implementation "org.springframework.boot:spring-boot-starter-web:${springVersion}" + implementation "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:${springCloudVersion}" + implementation "org.springframework.cloud:spring-cloud-starter-openfeign:${springCloudVersion}" + integrationTestImplementation 'org.assertj:assertj-core:3.23.1' + integrationTestImplementation "org.springframework.boot:spring-boot-starter-test:${springVersion}" + runtimeOnly 'mysql:mysql-connector-java:8.0.30' + testImplementation 'org.assertj:assertj-core:3.23.1' + testImplementation "org.springframework.boot:spring-boot-starter-test:${springVersion}" +} + +configurations { + integrationTestImplementation.extendsFrom implementation + integrationTestRuntimeOnly.extendsFrom runtimeOnly +} + +// configure the integrationTest to run as part of a regular build +// tasks.named('check') { +// dependsOn(testing.suites.integrationTest) +// } + +test { + useJUnitPlatform() + + testLogging.showStandardStreams = true + + beforeTest { descriptor -> + logger.lifecycle("Running test: " + descriptor) + } + + failFast = true + + testLogging { + events("passed", "skipped", "failed") + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +openApi { + apiDocsUrl.set("http://localhost:8083/api/v1/api-docs/openapi.json.yaml") + outputDir.set(file("docs")) + outputFileName.set("openapi.yaml") +} diff --git a/apps/challenge-user-service/pom.xml b/apps/challenge-user-service/pom.xml new file mode 100644 index 0000000000..6ebfb6b83a --- /dev/null +++ b/apps/challenge-user-service/pom.xml @@ -0,0 +1,80 @@ + + 4.0.0 + org.openapitools + openapi-spring + jar + openapi-spring + v1.0 + + 1.8 + ${java.version} + ${java.version} + UTF-8 + 1.6.8 + 4.10.3 + + + org.springframework.boot + spring-boot-starter-parent + 2.7.0 + + + + src/main/java + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.data + spring-data-commons + + + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + org.openapitools + jackson-databind-nullable + 0.2.2 + + + + org.springframework.boot + spring-boot-starter-validation + + + com.fasterxml.jackson.core + jackson-databind + + + org.springframework.boot + spring-boot-starter-test + test + + + diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java deleted file mode 100644 index fae0cab306..0000000000 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/User.java +++ /dev/null @@ -1,243 +0,0 @@ -package org.sagebionetworks.challenge.model.dto; - -import java.net.URI; -import java.util.Objects; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; -import org.openapitools.jackson.nullable.JsonNullable; -import java.time.OffsetDateTime; -import javax.validation.Valid; -import javax.validation.constraints.*; -import io.swagger.v3.oas.annotations.media.Schema; - - -import java.util.*; -import javax.annotation.Generated; - -/** - * User - */ - -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class User { - - @JsonProperty("id") - private Long id; - - @JsonProperty("username") - private String username; - - @JsonProperty("email") - private String email; - - @JsonProperty("password") - private String password; - - @JsonProperty("authId") - private String authId; - - /** - * Gets or Sets status - */ - public enum StatusEnum { - PENDING("PENDING"), - - APPROVED("APPROVED"), - - DISABLED("DISABLED"), - - BLACKLIST("BLACKLIST"); - - private String value; - - StatusEnum(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - @JsonCreator - public static StatusEnum fromValue(String value) { - for (StatusEnum b : StatusEnum.values()) { - if (b.value.equals(value)) { - return b; - } - } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); - } - } - - @JsonProperty("status") - private StatusEnum status; - - public User id(Long id) { - this.id = id; - return this; - } - - /** - * Get id - * @return id - */ - - @Schema(name = "id", required = false) - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public User username(String username) { - this.username = username; - return this; - } - - /** - * Get username - * @return username - */ - - @Schema(name = "username", required = false) - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public User email(String email) { - this.email = email; - return this; - } - - /** - * Get email - * @return email - */ - - @Schema(name = "email", required = false) - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public User password(String password) { - this.password = password; - return this; - } - - /** - * Get password - * @return password - */ - - @Schema(name = "password", required = false) - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public User authId(String authId) { - this.authId = authId; - return this; - } - - /** - * Get authId - * @return authId - */ - - @Schema(name = "authId", required = false) - public String getAuthId() { - return authId; - } - - public void setAuthId(String authId) { - this.authId = authId; - } - - public User status(StatusEnum status) { - this.status = status; - return this; - } - - /** - * Get status - * @return status - */ - - @Schema(name = "status", required = false) - public StatusEnum getStatus() { - return status; - } - - public void setStatus(StatusEnum status) { - this.status = status; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - User user = (User) o; - return Objects.equals(this.id, user.id) && - Objects.equals(this.username, user.username) && - Objects.equals(this.email, user.email) && - Objects.equals(this.password, user.password) && - Objects.equals(this.authId, user.authId) && - Objects.equals(this.status, user.status); - } - - @Override - public int hashCode() { - return Objects.hash(id, username, email, password, authId, status); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class User {\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" username: ").append(toIndentedString(username)).append("\n"); - sb.append(" email: ").append(toIndentedString(email)).append("\n"); - sb.append(" password: ").append(toIndentedString(password)).append("\n"); - sb.append(" authId: ").append(toIndentedString(authId)).append("\n"); - sb.append(" status: ").append(toIndentedString(status)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java deleted file mode 100644 index a3e77bf978..0000000000 --- a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.sagebionetworks.challenge.model.dto; - -import java.net.URI; -import java.util.Objects; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; -import org.openapitools.jackson.nullable.JsonNullable; -import java.time.OffsetDateTime; -import javax.validation.Valid; -import javax.validation.constraints.*; -import io.swagger.v3.oas.annotations.media.Schema; - - -import java.util.*; -import javax.annotation.Generated; - -/** - * UserUpdateRequest - */ - -@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class UserUpdateRequest { - - /** - * Gets or Sets status - */ - public enum StatusEnum { - PENDING("PENDING"), - - APPROVED("APPROVED"), - - DISABLED("DISABLED"), - - BLACKLIST("BLACKLIST"); - - private String value; - - StatusEnum(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - @JsonCreator - public static StatusEnum fromValue(String value) { - for (StatusEnum b : StatusEnum.values()) { - if (b.value.equals(value)) { - return b; - } - } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); - } - } - - @JsonProperty("status") - private StatusEnum status; - - public UserUpdateRequest status(StatusEnum status) { - this.status = status; - return this; - } - - /** - * Get status - * @return status - */ - - @Schema(name = "status", required = false) - public StatusEnum getStatus() { - return status; - } - - public void setStatus(StatusEnum status) { - this.status = status; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - UserUpdateRequest userUpdateRequest = (UserUpdateRequest) o; - return Objects.equals(this.status, userUpdateRequest.status); - } - - @Override - public int hashCode() { - return Objects.hash(status); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class UserUpdateRequest {\n"); - sb.append(" status: ").append(toIndentedString(status)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } -} - diff --git a/apps/challenge-user-service/src/integrationTest/java/org/sagebionetworks/challenge/ChallengeUserServiceApplicationTests.java b/apps/challenge-user-service/src.old/integrationTest/java/org/sagebionetworks/challenge/ChallengeUserServiceApplicationTests.java similarity index 100% rename from apps/challenge-user-service/src/integrationTest/java/org/sagebionetworks/challenge/ChallengeUserServiceApplicationTests.java rename to apps/challenge-user-service/src.old/integrationTest/java/org/sagebionetworks/challenge/ChallengeUserServiceApplicationTests.java diff --git a/apps/challenge-user-service/src/integrationTest/java/org/sagebionetworks/challenge/model/repository/UserRepositoryIntegrationTest.java b/apps/challenge-user-service/src.old/integrationTest/java/org/sagebionetworks/challenge/model/repository/UserRepositoryIntegrationTest.java similarity index 100% rename from apps/challenge-user-service/src/integrationTest/java/org/sagebionetworks/challenge/model/repository/UserRepositoryIntegrationTest.java rename to apps/challenge-user-service/src.old/integrationTest/java/org/sagebionetworks/challenge/model/repository/UserRepositoryIntegrationTest.java diff --git a/apps/challenge-user-service/src/integrationTest/resources/application.yml b/apps/challenge-user-service/src.old/integrationTest/resources/application.yml similarity index 100% rename from apps/challenge-user-service/src/integrationTest/resources/application.yml rename to apps/challenge-user-service/src.old/integrationTest/resources/application.yml diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/CustomFeignClientConfiguration.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/CustomFeignClientConfiguration.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/CustomFeignClientConfiguration.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/CustomFeignClientConfiguration.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/CustomFeignErrorDecoder.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/CustomFeignErrorDecoder.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/CustomFeignErrorDecoder.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/CustomFeignErrorDecoder.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakConfiguration.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/KeycloakConfiguration.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakConfiguration.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/KeycloakConfiguration.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManager.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/KeycloakManager.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManager.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/KeycloakManager.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManagerProperties.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/KeycloakManagerProperties.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManagerProperties.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/KeycloakManagerProperties.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/OpenApiConfiguration.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/OpenApiConfiguration.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/OpenApiConfiguration.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/OpenApiConfiguration.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SecurityConfiguration.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/SecurityConfiguration.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SecurityConfiguration.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/configuration/SecurityConfiguration.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/controller/UserController.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/controller/UserController.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/controller/UserController.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/controller/UserController.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/GlobalErrorCode.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/exception/GlobalErrorCode.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/GlobalErrorCode.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/exception/GlobalErrorCode.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidEmailException.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/exception/InvalidEmailException.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidEmailException.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/exception/InvalidEmailException.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidUserException.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/exception/InvalidUserException.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidUserException.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/exception/InvalidUserException.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/UserAlreadyRegisteredException.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/exception/UserAlreadyRegisteredException.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/UserAlreadyRegisteredException.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/exception/UserAlreadyRegisteredException.java diff --git a/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/dto/User.java new file mode 100644 index 0000000000..b2c1bfc03f --- /dev/null +++ b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/dto/User.java @@ -0,0 +1,25 @@ +package org.sagebionetworks.challenge.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class User { + private Long id; + private String username; + private String email; + private String password; + private String authId; + private UserStatus status; + + // public User(String username, String email, String password) { + // this.username = username; + // this.email = email; + // this.password = password; + // } +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java diff --git a/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java new file mode 100644 index 0000000000..fea5e08dad --- /dev/null +++ b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java @@ -0,0 +1,8 @@ +package org.sagebionetworks.challenge.model.dto; + +import lombok.Data; + +@Data +public class UserUpdateRequest { + private UserStatus status; +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/repository/UserRepository.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/repository/UserRepository.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/repository/UserRepository.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/repository/UserRepository.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/AccountResponse.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/rest/response/AccountResponse.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/AccountResponse.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/rest/response/AccountResponse.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/UserResponse.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/rest/response/UserResponse.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/UserResponse.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/model/rest/response/UserResponse.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/KeycloakUserService.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/service/KeycloakUserService.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/KeycloakUserService.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/service/KeycloakUserService.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/service/UserService.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/service/UserService.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/rest/ChallengeCoreRestClient.java b/apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/service/rest/ChallengeCoreRestClient.java similarity index 100% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/rest/ChallengeCoreRestClient.java rename to apps/challenge-user-service/src.old/main/java/org/sagebionetworks/challenge/service/rest/ChallengeCoreRestClient.java diff --git a/apps/challenge-user-service/src/main/resources/application.yml b/apps/challenge-user-service/src.old/main/resources/application.yml similarity index 100% rename from apps/challenge-user-service/src/main/resources/application.yml rename to apps/challenge-user-service/src.old/main/resources/application.yml diff --git a/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174638__create_user_table.sql b/apps/challenge-user-service/src.old/main/resources/db/migration/V1.0.20210427174638__create_user_table.sql similarity index 100% rename from apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174638__create_user_table.sql rename to apps/challenge-user-service/src.old/main/resources/db/migration/V1.0.20210427174638__create_user_table.sql diff --git a/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql b/apps/challenge-user-service/src.old/main/resources/db/migration/V1.0.20210427174721__temp_data.sql similarity index 100% rename from apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql rename to apps/challenge-user-service/src.old/main/resources/db/migration/V1.0.20210427174721__temp_data.sql diff --git a/apps/challenge-user-service/src/test/java/org/sagebionetworks/challenge/controller/UserControllerTest.java b/apps/challenge-user-service/src.old/test/java/org/sagebionetworks/challenge/controller/UserControllerTest.java similarity index 100% rename from apps/challenge-user-service/src/test/java/org/sagebionetworks/challenge/controller/UserControllerTest.java rename to apps/challenge-user-service/src.old/test/java/org/sagebionetworks/challenge/controller/UserControllerTest.java diff --git a/apps/challenge-user-service/src/test/java/org/sagebionetworks/challenge/service/UserServiceTest.java b/apps/challenge-user-service/src.old/test/java/org/sagebionetworks/challenge/service/UserServiceTest.java similarity index 100% rename from apps/challenge-user-service/src/test/java/org/sagebionetworks/challenge/service/UserServiceTest.java rename to apps/challenge-user-service/src.old/test/java/org/sagebionetworks/challenge/service/UserServiceTest.java diff --git a/apps/challenge-user-service/src/test/resources/application.yml b/apps/challenge-user-service/src.old/test/resources/application.yml similarity index 100% rename from apps/challenge-user-service/src/test/resources/application.yml rename to apps/challenge-user-service/src.old/test/resources/application.yml diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java similarity index 100% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java similarity index 100% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java similarity index 100% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java similarity index 100% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java similarity index 100% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java similarity index 100% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java similarity index 100% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java diff --git a/apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java similarity index 100% rename from apps/challenge-user-service/server/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java index b2c1bfc03f..fae0cab306 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java @@ -1,25 +1,243 @@ package org.sagebionetworks.challenge.model.dto; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; + + +import java.util.*; +import javax.annotation.Generated; + +/** + * User + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") public class User { + + @JsonProperty("id") private Long id; + + @JsonProperty("username") private String username; + + @JsonProperty("email") private String email; + + @JsonProperty("password") private String password; + + @JsonProperty("authId") private String authId; - private UserStatus status; - // public User(String username, String email, String password) { - // this.username = username; - // this.email = email; - // this.password = password; - // } + /** + * Gets or Sets status + */ + public enum StatusEnum { + PENDING("PENDING"), + + APPROVED("APPROVED"), + + DISABLED("DISABLED"), + + BLACKLIST("BLACKLIST"); + + private String value; + + StatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static StatusEnum fromValue(String value) { + for (StatusEnum b : StatusEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + @JsonProperty("status") + private StatusEnum status; + + public User id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + */ + + @Schema(name = "id", required = false) + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public User username(String username) { + this.username = username; + return this; + } + + /** + * Get username + * @return username + */ + + @Schema(name = "username", required = false) + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public User email(String email) { + this.email = email; + return this; + } + + /** + * Get email + * @return email + */ + + @Schema(name = "email", required = false) + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public User password(String password) { + this.password = password; + return this; + } + + /** + * Get password + * @return password + */ + + @Schema(name = "password", required = false) + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public User authId(String authId) { + this.authId = authId; + return this; + } + + /** + * Get authId + * @return authId + */ + + @Schema(name = "authId", required = false) + public String getAuthId() { + return authId; + } + + public void setAuthId(String authId) { + this.authId = authId; + } + + public User status(StatusEnum status) { + this.status = status; + return this; + } + + /** + * Get status + * @return status + */ + + @Schema(name = "status", required = false) + public StatusEnum getStatus() { + return status; + } + + public void setStatus(StatusEnum status) { + this.status = status; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + User user = (User) o; + return Objects.equals(this.id, user.id) && + Objects.equals(this.username, user.username) && + Objects.equals(this.email, user.email) && + Objects.equals(this.password, user.password) && + Objects.equals(this.authId, user.authId) && + Objects.equals(this.status, user.status); + } + + @Override + public int hashCode() { + return Objects.hash(id, username, email, password, authId, status); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class User {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" username: ").append(toIndentedString(username)).append("\n"); + sb.append(" email: ").append(toIndentedString(email)).append("\n"); + sb.append(" password: ").append(toIndentedString(password)).append("\n"); + sb.append(" authId: ").append(toIndentedString(authId)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } } + diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java index fea5e08dad..a3e77bf978 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java @@ -1,8 +1,123 @@ package org.sagebionetworks.challenge.model.dto; -import lombok.Data; +import java.net.URI; +import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import org.openapitools.jackson.nullable.JsonNullable; +import java.time.OffsetDateTime; +import javax.validation.Valid; +import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; -@Data + +import java.util.*; +import javax.annotation.Generated; + +/** + * UserUpdateRequest + */ + +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") public class UserUpdateRequest { - private UserStatus status; + + /** + * Gets or Sets status + */ + public enum StatusEnum { + PENDING("PENDING"), + + APPROVED("APPROVED"), + + DISABLED("DISABLED"), + + BLACKLIST("BLACKLIST"); + + private String value; + + StatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static StatusEnum fromValue(String value) { + for (StatusEnum b : StatusEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + @JsonProperty("status") + private StatusEnum status; + + public UserUpdateRequest status(StatusEnum status) { + this.status = status; + return this; + } + + /** + * Get status + * @return status + */ + + @Schema(name = "status", required = false) + public StatusEnum getStatus() { + return status; + } + + public void setStatus(StatusEnum status) { + this.status = status; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UserUpdateRequest userUpdateRequest = (UserUpdateRequest) o; + return Objects.equals(this.status, userUpdateRequest.status); + } + + @Override + public int hashCode() { + return Objects.hash(status); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class UserUpdateRequest {\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } } + diff --git a/apps/challenge-user-service/server/src/main/resources/application.properties b/apps/challenge-user-service/src/main/resources/application.properties similarity index 100% rename from apps/challenge-user-service/server/src/main/resources/application.properties rename to apps/challenge-user-service/src/main/resources/application.properties diff --git a/apps/challenge-user-service/server/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml similarity index 100% rename from apps/challenge-user-service/server/src/main/resources/openapi.yaml rename to apps/challenge-user-service/src/main/resources/openapi.yaml diff --git a/apps/challenge-user-service/server/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java b/apps/challenge-user-service/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java similarity index 100% rename from apps/challenge-user-service/server/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java rename to apps/challenge-user-service/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java From 3f3b52f2828f95eef2e704d887f4a98d649f214c Mon Sep 17 00:00:00 2001 From: tschaffter Date: Fri, 16 Sep 2022 20:54:14 +0000 Subject: [PATCH 10/62] Disable testing of the user service for now --- apps/challenge-user-service/project.json | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/challenge-user-service/project.json b/apps/challenge-user-service/project.json index df34e640a7..f0b1536e23 100644 --- a/apps/challenge-user-service/project.json +++ b/apps/challenge-user-service/project.json @@ -31,22 +31,22 @@ "^install" ] }, - "test": { - "executor": "@nxrocks/nx-spring-boot:test", - "options": { - "root": "apps/challenge-user-service" - }, - "dependsOn": ["build"] - }, - "integration-test": { - "executor": "@nrwl/workspace:run-commands", - "options": { - "commands": [ - "./gradlew integrationTest" - ], - "cwd": "apps/challenge-user-service" - } - }, + // "test": { + // "executor": "@nxrocks/nx-spring-boot:test", + // "options": { + // "root": "apps/challenge-user-service" + // }, + // "dependsOn": ["build"] + // }, + // "integration-test": { + // "executor": "@nrwl/workspace:run-commands", + // "options": { + // "commands": [ + // "./gradlew integrationTest" + // ], + // "cwd": "apps/challenge-user-service" + // } + // }, "clean": { "executor": "@nxrocks/nx-spring-boot:clean", "options": { From cc12f69f58d06bf4acc78b703ec853e9505798d2 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 16 Sep 2022 22:47:37 +0000 Subject: [PATCH 11/62] Add files to .openapi-generator-ignore --- .../.openapi-generator-ignore | 2 + .../.openapi-generator/FILES | 14 + .../.openapi-generator/VERSION | 1 + apps/challenge-user-service/openapitools.json | 2 +- apps/challenge-user-service/pom.xml | 80 ----- apps/challenge-user-service/pom.xml.disable | 319 ------------------ 6 files changed, 18 insertions(+), 400 deletions(-) create mode 100644 apps/challenge-user-service/.openapi-generator-ignore create mode 100644 apps/challenge-user-service/.openapi-generator/FILES create mode 100644 apps/challenge-user-service/.openapi-generator/VERSION delete mode 100644 apps/challenge-user-service/pom.xml delete mode 100644 apps/challenge-user-service/pom.xml.disable diff --git a/apps/challenge-user-service/.openapi-generator-ignore b/apps/challenge-user-service/.openapi-generator-ignore new file mode 100644 index 0000000000..1a1684ffb8 --- /dev/null +++ b/apps/challenge-user-service/.openapi-generator-ignore @@ -0,0 +1,2 @@ +pom.xml +README.md \ No newline at end of file diff --git a/apps/challenge-user-service/.openapi-generator/FILES b/apps/challenge-user-service/.openapi-generator/FILES new file mode 100644 index 0000000000..642ff71e57 --- /dev/null +++ b/apps/challenge-user-service/.openapi-generator/FILES @@ -0,0 +1,14 @@ +pom.xml +src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java +src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java +src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java +src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java +src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java +src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java +src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java +src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java +src/main/java/org/sagebionetworks/challenge/model/dto/User.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +src/main/resources/application.properties +src/main/resources/openapi.yaml +src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/.openapi-generator/VERSION b/apps/challenge-user-service/.openapi-generator/VERSION new file mode 100644 index 0000000000..358e78e607 --- /dev/null +++ b/apps/challenge-user-service/.openapi-generator/VERSION @@ -0,0 +1 @@ +6.1.0 \ No newline at end of file diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index a2e15f3b07..96fa74b54b 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -6,7 +6,7 @@ "generators": { "challenge-user-service": { "generatorName": "spring", - "output": "server", + "output": "#{cwd}", "inputSpec": "openapi.yaml", "templateDir": "templates", "additionalProperties": { diff --git a/apps/challenge-user-service/pom.xml b/apps/challenge-user-service/pom.xml deleted file mode 100644 index 6ebfb6b83a..0000000000 --- a/apps/challenge-user-service/pom.xml +++ /dev/null @@ -1,80 +0,0 @@ - - 4.0.0 - org.openapitools - openapi-spring - jar - openapi-spring - v1.0 - - 1.8 - ${java.version} - ${java.version} - UTF-8 - 1.6.8 - 4.10.3 - - - org.springframework.boot - spring-boot-starter-parent - 2.7.0 - - - - src/main/java - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.data - spring-data-commons - - - - org.springdoc - springdoc-openapi-ui - ${springdoc.version} - - - - com.google.code.findbugs - jsr305 - 3.0.2 - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - - - org.openapitools - jackson-databind-nullable - 0.2.2 - - - - org.springframework.boot - spring-boot-starter-validation - - - com.fasterxml.jackson.core - jackson-databind - - - org.springframework.boot - spring-boot-starter-test - test - - - diff --git a/apps/challenge-user-service/pom.xml.disable b/apps/challenge-user-service/pom.xml.disable deleted file mode 100644 index a8d3762b1e..0000000000 --- a/apps/challenge-user-service/pom.xml.disable +++ /dev/null @@ -1,319 +0,0 @@ - - - 4.0.0 - - - org.springframework.boot - spring-boot-starter-parent - 2.7.0 - - - - - org.sagebionetworks.challenge - challenge-user-service - 0.0.1-SNAPSHOT - challenge-user-service - Demo project for Spring Boot - - - 17 - 2021.0.3 - 2.7.2 - 18.0.0 - false - true - ${basedir}/../../checkstyle.xml - - - - - org.springframework.boot - spring-boot-starter-data-jpa - ${spring-boot.version} - - - org.springframework.boot - spring-boot-starter-actuator - ${spring-boot.version} - - - org.springframework.boot - spring-boot-starter-web - ${spring-boot.version} - - - org.springframework.boot - spring-boot-starter-security - ${spring-boot.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - 3.1.3 - - - javax.ws.rs - jsr311-api - - - - - org.springframework.cloud - spring-cloud-starter-openfeign - 3.1.3 - - - org.springdoc - springdoc-openapi-ui - 1.6.9 - - - org.flywaydb - flyway-core - 9.1.2 - - - org.flywaydb - flyway-mysql - 9.1.2 - - - org.keycloak - keycloak-spring-boot-starter - ${keycloak.version} - - - mysql - mysql-connector-java - 8.0.30 - runtime - - - org.projectlombok - lombok - 1.18.24 - true - - - org.keycloak - keycloak-admin-client - ${keycloak.version} - - - - org.springframework.boot - spring-boot-starter-test - ${spring-boot.version} - test - - - org.springframework.boot - spring-boot-devtools - ${spring-boot.version} - true - - - com.h2database - h2 - 2.1.214 - - - - - org.assertj - assertj-core - 3.23.1 - test - - - - org.sagebionetworks.challenge - challenge-util - 0.0.1-SNAPSHOT - - - - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - org.keycloak.bom - keycloak-adapter-bom - ${keycloak.version} - pom - import - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - - pre-integration-test - - start - - - - integration-test - - ${skip.integration.tests} - - - - post-integration-test - - stop - - - ${skip.integration.tests} - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - **/*IntegrationTest.java - **/*ApplicationTests.java - - ${skip.unit.tests} - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.22.2 - - - **/*IntegrationTest.java - **/*ApplicationTests.java - - ${skip.integration.tests} - - - - - integration-test - verify - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.3.0 - - - add-integration-test-source - generate-test-sources - - add-test-source - - - - src/integration-test/java - - - - - add-integration-resource - generate-resources - - add-resource - - - - - src/integration-test/resources - - - - - - - - - org.springdoc - springdoc-openapi-maven-plugin - 1.4 - - - integration-test - - generate - - - - integration-test - - ${skip.integration.tests} - - - - - http://localhost:8083/api/v1/api-docs/openapi.json - openapi.json - openapi - false - - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.1.2 - - - com.puppycrawl.tools - checkstyle - 10.3 - - - - - - - - - - dev - - true - - - - integration-test - - true - false - - - - From 2630aedd499a1f6e97d408848e1c4383ce7b69b3 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 16 Sep 2022 23:00:14 +0000 Subject: [PATCH 12/62] Give more control over templates --- apps/challenge-user-service/.openapi-generator/FILES | 2 +- apps/challenge-user-service/AUTHORS.md | 1 + apps/challenge-user-service/openapitools.json | 7 ++++--- apps/challenge-user-service/templates/AUTHORS.md | 1 + apps/challenge-user-service/templates/config.yaml | 2 ++ 5 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 apps/challenge-user-service/AUTHORS.md create mode 100644 apps/challenge-user-service/templates/AUTHORS.md create mode 100644 apps/challenge-user-service/templates/config.yaml diff --git a/apps/challenge-user-service/.openapi-generator/FILES b/apps/challenge-user-service/.openapi-generator/FILES index 642ff71e57..e2565ebfba 100644 --- a/apps/challenge-user-service/.openapi-generator/FILES +++ b/apps/challenge-user-service/.openapi-generator/FILES @@ -1,4 +1,4 @@ -pom.xml +AUTHORS.md src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java diff --git a/apps/challenge-user-service/AUTHORS.md b/apps/challenge-user-service/AUTHORS.md new file mode 100644 index 0000000000..8318c86b35 --- /dev/null +++ b/apps/challenge-user-service/AUTHORS.md @@ -0,0 +1 @@ +Test \ No newline at end of file diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index 96fa74b54b..152a6b6d47 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -5,17 +5,18 @@ "version": "6.1.0", "generators": { "challenge-user-service": { + "config": "templates/config.yaml", "generatorName": "spring", - "output": "#{cwd}", "inputSpec": "openapi.yaml", + "output": "#{cwd}", "templateDir": "templates", "additionalProperties": { - "basePackage": "org.sagebionetworks.challenge", "apiPackage": "org.sagebionetworks.challenge.api", - "modelPackage": "org.sagebionetworks.challenge.model.dto", + "basePackage": "org.sagebionetworks.challenge", "configPackage": "org.sagebionetworks.challenge.configuration", "delegatePattern": true, "hideGenerationTimestamp": true, + "modelPackage": "org.sagebionetworks.challenge.model.dto", "useTags": true } } diff --git a/apps/challenge-user-service/templates/AUTHORS.md b/apps/challenge-user-service/templates/AUTHORS.md new file mode 100644 index 0000000000..8318c86b35 --- /dev/null +++ b/apps/challenge-user-service/templates/AUTHORS.md @@ -0,0 +1 @@ +Test \ No newline at end of file diff --git a/apps/challenge-user-service/templates/config.yaml b/apps/challenge-user-service/templates/config.yaml new file mode 100644 index 0000000000..0d95f7892a --- /dev/null +++ b/apps/challenge-user-service/templates/config.yaml @@ -0,0 +1,2 @@ +files: + AUTHORS.md: {} \ No newline at end of file From 3068ea181a141907a4301d64ca9a8f3ae5373ec1 Mon Sep 17 00:00:00 2001 From: tschaffter Date: Sat, 17 Sep 2022 02:32:48 +0000 Subject: [PATCH 13/62] Update AUTHORS.md --- apps/challenge-user-service/AUTHORS.md | 12 +++++++++++- apps/challenge-user-service/templates/AUTHORS.md | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/challenge-user-service/AUTHORS.md b/apps/challenge-user-service/AUTHORS.md index 8318c86b35..01c10d9f06 100644 --- a/apps/challenge-user-service/AUTHORS.md +++ b/apps/challenge-user-service/AUTHORS.md @@ -1 +1,11 @@ -Test \ No newline at end of file +# Authors + +Ordered by first contribution. + +- [Thomas Schaffter](https://github.com/tschaffter) + + + + + diff --git a/apps/challenge-user-service/templates/AUTHORS.md b/apps/challenge-user-service/templates/AUTHORS.md index 8318c86b35..30c49f3980 100644 --- a/apps/challenge-user-service/templates/AUTHORS.md +++ b/apps/challenge-user-service/templates/AUTHORS.md @@ -1 +1,11 @@ -Test \ No newline at end of file +# Authors + +#### Ordered by first contribution. + +- [Thomas Schaffter](https://github.com/tschaffter) + + + + + From 9563744c10bded243bd6c5fbf524d46fc6d8ab8b Mon Sep 17 00:00:00 2001 From: tschaffter Date: Sat, 17 Sep 2022 02:51:21 +0000 Subject: [PATCH 14/62] Upgrade to Spring Boot 2.7.3 --- apps/challenge-user-service/build.gradle | 49 ++++++++++++++---------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index 09e770c5fb..6e9161996d 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -1,32 +1,41 @@ plugins { - id 'java' - id 'org.springframework.boot' version '2.7.3' + id 'java' + id 'org.springframework.boot' version '2.7.3' +} + +ext { + springBootVersion = '2.7.3' + springDataVersion = '2.7.2' + springCloudVersion = '3.1.3' + keycloakVersion = '18.0.0' } repositories { - mavenLocal() - maven { - url = uri('https://repo.maven.apache.org/maven2/') - } + mavenCentral() + mavenLocal() } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web:2.7.0' - implementation 'org.springframework.data:spring-data-commons:2.7.0' - implementation 'org.springdoc:springdoc-openapi-ui:1.6.8' - implementation 'com.google.code.findbugs:jsr305:3.0.2' - implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.3' - implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3' - implementation 'org.openapitools:jackson-databind-nullable:0.2.2' - implementation 'org.springframework.boot:spring-boot-starter-validation:2.7.0' - implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3' - testImplementation 'org.springframework.boot:spring-boot-starter-test:2.7.0' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3' + implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.3' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3' + implementation 'com.google.code.findbugs:jsr305:3.0.2' + implementation 'org.openapitools:jackson-databind-nullable:0.2.2' + implementation 'org.springdoc:springdoc-openapi-ui:1.6.8' + implementation "org.springframework.boot:spring-boot-starter-validation:${springBootVersion}" + implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" + implementation "org.springframework.data:spring-data-commons:${springDataVersion}" + testImplementation "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" } -group = 'org.openapitools' -version = 'v1.0' -description = 'openapi-spring' -java.sourceCompatibility = JavaVersion.VERSION_1_8 +group = 'org.sagebionetworks.challenge' +version = '0.0.1-SNAPSHOT' + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } +} tasks.withType(JavaCompile) { options.encoding = 'UTF-8' From cfae75006d5fe1c812ec68024357b7aab27d2229 Mon Sep 17 00:00:00 2001 From: tschaffter Date: Sat, 17 Sep 2022 03:01:36 +0000 Subject: [PATCH 15/62] Rename app class --- .../.openapi-generator-ignore | 5 ++++- ...a => ChallengeUserServiceApplication.java} | 21 ++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/{OpenApiGeneratorApplication.java => ChallengeUserServiceApplication.java} (58%) diff --git a/apps/challenge-user-service/.openapi-generator-ignore b/apps/challenge-user-service/.openapi-generator-ignore index 1a1684ffb8..01b32bd8a2 100644 --- a/apps/challenge-user-service/.openapi-generator-ignore +++ b/apps/challenge-user-service/.openapi-generator-ignore @@ -1,2 +1,5 @@ pom.xml -README.md \ No newline at end of file +README.md + +# Ignore our Spring Boot application class +**/OpenApiGeneratorApplication.java \ No newline at end of file diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java similarity index 58% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java index 1eddb57b27..447639b4e7 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java @@ -8,16 +8,17 @@ import org.springframework.context.annotation.ComponentScan; @SpringBootApplication -@ComponentScan(basePackages = {"org.sagebionetworks.challenge", "org.sagebionetworks.challenge.api" , "org.sagebionetworks.challenge.configuration"}) -public class OpenApiGeneratorApplication { +@ComponentScan(basePackages = {"org.sagebionetworks.challenge", "org.sagebionetworks.challenge.api", + "org.sagebionetworks.challenge.configuration"}) +public class ChallengeUserServiceApplication { - public static void main(String[] args) { - SpringApplication.run(OpenApiGeneratorApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(ChallengeUserServiceApplication.class, args); + } - @Bean - public Module jsonNullableModule() { - return new JsonNullableModule(); - } + @Bean + public Module jsonNullableModule() { + return new JsonNullableModule(); + } -} \ No newline at end of file +} From c7e347d418911d78b40dbfc4e8a4e9bd71321aa4 Mon Sep 17 00:00:00 2001 From: tschaffter Date: Sat, 17 Sep 2022 03:03:29 +0000 Subject: [PATCH 16/62] Review app class --- apps/challenge-user-service/.openapi-generator/FILES | 1 - apps/challenge-user-service/templates/AUTHORS.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/challenge-user-service/.openapi-generator/FILES b/apps/challenge-user-service/.openapi-generator/FILES index e2565ebfba..1c3a6bff11 100644 --- a/apps/challenge-user-service/.openapi-generator/FILES +++ b/apps/challenge-user-service/.openapi-generator/FILES @@ -1,5 +1,4 @@ AUTHORS.md -src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java diff --git a/apps/challenge-user-service/templates/AUTHORS.md b/apps/challenge-user-service/templates/AUTHORS.md index 30c49f3980..01c10d9f06 100644 --- a/apps/challenge-user-service/templates/AUTHORS.md +++ b/apps/challenge-user-service/templates/AUTHORS.md @@ -1,6 +1,6 @@ # Authors -#### Ordered by first contribution. +Ordered by first contribution. - [Thomas Schaffter](https://github.com/tschaffter) From f0e4d92aef219cd09d233c1d59076884a6e611ad Mon Sep 17 00:00:00 2001 From: tschaffter Date: Sat, 17 Sep 2022 03:07:29 +0000 Subject: [PATCH 17/62] Update fasterxml dependencies --- apps/challenge-user-service/build.gradle | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index 6e9161996d..9f3b7ba6d5 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -4,10 +4,11 @@ plugins { } ext { + fasterxmlVersion = '2.13.4' + keycloakVersion = '18.0.0' springBootVersion = '2.7.3' - springDataVersion = '2.7.2' springCloudVersion = '3.1.3' - keycloakVersion = '18.0.0' + springDataVersion = '2.7.2' } repositories { @@ -16,9 +17,9 @@ repositories { } dependencies { - implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3' - implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.3' - implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3' + implementation "com.fasterxml.jackson.core:jackson-databind:${fasterxmlVersion}" + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${fasterxmlVersion}" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${fasterxmlVersion}" implementation 'com.google.code.findbugs:jsr305:3.0.2' implementation 'org.openapitools:jackson-databind-nullable:0.2.2' implementation 'org.springdoc:springdoc-openapi-ui:1.6.8' From 2b117f2134b95196bf62cdb27f21bf1854ebe41a Mon Sep 17 00:00:00 2001 From: tschaffter Date: Tue, 20 Sep 2022 21:00:47 +0000 Subject: [PATCH 18/62] Add project task `generate-code` --- apps/challenge-user-service/build.gradle | 1 + apps/challenge-user-service/project.json | 13 +- .../challenge/RFC3339DateFormat.java | 8 +- .../challenge/api/ApiUtil.java | 23 +- .../challenge/api/UserControllerApi.java | 254 +++++++++--------- .../api/UserControllerApiController.java | 44 +-- .../api/UserControllerApiDelegate.java | 182 ++++++------- .../configuration/HomeController.java | 18 +- .../configuration/SpringDocConfiguration.java | 50 ++-- .../challenge/model/dto/User.java | 67 ++--- .../model/dto/UserUpdateRequest.java | 35 +-- .../OpenApiGeneratorApplicationTests.java | 8 +- 12 files changed, 321 insertions(+), 382 deletions(-) diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index 0d9dc7dbbf..79a85486c4 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'org.springframework.boot' version '2.7.3' + id 'com.diffplug.spotless' version '6.8.0' } ext { diff --git a/apps/challenge-user-service/project.json b/apps/challenge-user-service/project.json index 12901849c4..22d8da38b8 100644 --- a/apps/challenge-user-service/project.json +++ b/apps/challenge-user-service/project.json @@ -86,13 +86,16 @@ }, "dependsOn": ["^install"] }, - "generate-openapi-definition": { + "generate-code": { "executor": "@nrwl/workspace:run-commands", "options": { - "command": "./gradlew clean generateOpenApiDocs", - "cwd": "apps/challenge-user-service" - }, - "dependsOn": ["prepare", "^serve-detach"] + "commands": [ + "openapi-generator-cli generate", + "./gradlew spotlessApply" + ], + "cwd": "apps/challenge-user-service", + "parallel": false + } } }, "tags": ["type:service", "scope:backend"], diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java index f7ae51cd36..54ab17bb8e 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java @@ -1,7 +1,6 @@ package org.sagebionetworks.challenge; import com.fasterxml.jackson.databind.util.StdDateFormat; - import java.text.DateFormat; import java.text.FieldPosition; import java.text.ParsePosition; @@ -13,9 +12,8 @@ public class RFC3339DateFormat extends DateFormat { private static final long serialVersionUID = 1L; private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC"); - private final StdDateFormat fmt = new StdDateFormat() - .withTimeZone(TIMEZONE_Z) - .withColonInTimeZone(true); + private final StdDateFormat fmt = + new StdDateFormat().withTimeZone(TIMEZONE_Z).withColonInTimeZone(true); public RFC3339DateFormat() { this.calendar = new GregorianCalendar(); @@ -35,4 +33,4 @@ public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fie public Object clone() { return this; } -} \ No newline at end of file +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java index de8997fba3..f0e94fc033 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java @@ -1,19 +1,18 @@ package org.sagebionetworks.challenge.api; -import org.springframework.web.context.request.NativeWebRequest; - -import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import org.springframework.web.context.request.NativeWebRequest; public class ApiUtil { - public static void setExampleResponse(NativeWebRequest req, String contentType, String example) { - try { - HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class); - res.setCharacterEncoding("UTF-8"); - res.addHeader("Content-Type", contentType); - res.getWriter().print(example); - } catch (IOException e) { - throw new RuntimeException(e); - } + public static void setExampleResponse(NativeWebRequest req, String contentType, String example) { + try { + HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class); + res.setCharacterEncoding("UTF-8"); + res.addHeader("Content-Type", contentType); + res.getWriter().print(example); + } catch (IOException e) { + throw new RuntimeException(e); } + } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java index 758a2284f3..6d8233ea11 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java @@ -1,30 +1,24 @@ /** * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (6.1.0). - * https://openapi-generator.tech - * Do not edit the class manually. + * https://openapi-generator.tech Do not edit the class manually. */ package org.sagebionetworks.challenge.api; -import org.sagebionetworks.challenge.model.dto.User; -import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; +import javax.annotation.Generated; +import javax.validation.Valid; +import javax.validation.constraints.*; +import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import javax.validation.Valid; -import javax.validation.constraints.*; -import java.util.List; -import java.util.Map; -import javax.annotation.Generated; @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @Validated @@ -32,123 +26,127 @@ @RequestMapping("${openapi.user.base-path:}") public interface UserControllerApi { - default UserControllerApiDelegate getDelegate() { - return new UserControllerApiDelegate() {}; - } - - /** - * POST /api/v1/users/register - * - * @param user (required) - * @return OK (status code 200) - */ - @Operation( - operationId = "createUser", - tags = { "user-controller" }, - responses = { - @ApiResponse(responseCode = "200", description = "OK", content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = User.class)) - }) - } - ) - @RequestMapping( - method = RequestMethod.POST, - value = "/api/v1/users/register", - produces = { "*/*" }, - consumes = { "application/json" } - ) - default ResponseEntity createUser( - @Parameter(name = "User", description = "", required = true) @Valid @RequestBody User user - ) { - return getDelegate().createUser(user); - } - - - /** - * GET /api/v1/users/{id} - * - * @param id (required) - * @return OK (status code 200) - */ - @Operation( - operationId = "getUser", - tags = { "user-controller" }, - responses = { - @ApiResponse(responseCode = "200", description = "OK", content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = User.class)) - }) - } - ) - @RequestMapping( - method = RequestMethod.GET, - value = "/api/v1/users/{id}", - produces = { "*/*" } - ) - default ResponseEntity getUser( - @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id - ) { - return getDelegate().getUser(id); - } - + default UserControllerApiDelegate getDelegate() { + return new UserControllerApiDelegate() {}; + } - /** - * GET /api/v1/users/ - * - * @param page Zero-based page index (0..N) (optional, default to 0) - * @param size The size of the page to be returned (optional, default to 20) - * @param sort Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. (optional) - * @return OK (status code 200) - */ - @Operation( - operationId = "listUsers", - tags = { "user-controller" }, - responses = { - @ApiResponse(responseCode = "200", description = "OK", content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = User.class)) - }) - } - ) - @RequestMapping( - method = RequestMethod.GET, - value = "/api/v1/users/", - produces = { "*/*" } - ) - default ResponseEntity> listUsers( - @Min(0) @Parameter(name = "page", description = "Zero-based page index (0..N)") @Valid @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, - @Min(1) @Parameter(name = "size", description = "The size of the page to be returned") @Valid @RequestParam(value = "size", required = false, defaultValue = "20") Integer size, - @Parameter(name = "sort", description = "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.") @Valid @RequestParam(value = "sort", required = false) List sort - ) { - return getDelegate().listUsers(page, size, sort); - } + /** + * POST /api/v1/users/register + * + * @param user (required) + * @return OK (status code 200) + */ + @Operation( + operationId = "createUser", + tags = {"user-controller"}, + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + }) + @RequestMapping( + method = RequestMethod.POST, + value = "/api/v1/users/register", + produces = {"*/*"}, + consumes = {"application/json"}) + default ResponseEntity createUser( + @Parameter(name = "User", description = "", required = true) @Valid @RequestBody User user) { + return getDelegate().createUser(user); + } + /** + * GET /api/v1/users/{id} + * + * @param id (required) + * @return OK (status code 200) + */ + @Operation( + operationId = "getUser", + tags = {"user-controller"}, + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + }) + @RequestMapping( + method = RequestMethod.GET, + value = "/api/v1/users/{id}", + produces = {"*/*"}) + default ResponseEntity getUser( + @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id) { + return getDelegate().getUser(id); + } - /** - * PATCH /api/v1/users/{id} - * - * @param id (required) - * @param userUpdateRequest (required) - * @return OK (status code 200) - */ - @Operation( - operationId = "updateUser", - tags = { "user-controller" }, - responses = { - @ApiResponse(responseCode = "200", description = "OK", content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = User.class)) - }) - } - ) - @RequestMapping( - method = RequestMethod.PATCH, - value = "/api/v1/users/{id}", - produces = { "*/*" }, - consumes = { "application/json" } - ) - default ResponseEntity updateUser( - @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id, - @Parameter(name = "UserUpdateRequest", description = "", required = true) @Valid @RequestBody UserUpdateRequest userUpdateRequest - ) { - return getDelegate().updateUser(id, userUpdateRequest); - } + /** + * GET /api/v1/users/ + * + * @param page Zero-based page index (0..N) (optional, default to 0) + * @param size The size of the page to be returned (optional, default to 20) + * @param sort Sorting criteria in the format: property,(asc|desc). Default sort order is + * ascending. Multiple sort criteria are supported. (optional) + * @return OK (status code 200) + */ + @Operation( + operationId = "listUsers", + tags = {"user-controller"}, + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + }) + @RequestMapping( + method = RequestMethod.GET, + value = "/api/v1/users/", + produces = {"*/*"}) + default ResponseEntity> listUsers( + @Min(0) + @Parameter(name = "page", description = "Zero-based page index (0..N)") + @Valid + @RequestParam(value = "page", required = false, defaultValue = "0") + Integer page, + @Min(1) + @Parameter(name = "size", description = "The size of the page to be returned") + @Valid + @RequestParam(value = "size", required = false, defaultValue = "20") + Integer size, + @Parameter( + name = "sort", + description = + "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.") + @Valid + @RequestParam(value = "sort", required = false) + List sort) { + return getDelegate().listUsers(page, size, sort); + } + /** + * PATCH /api/v1/users/{id} + * + * @param id (required) + * @param userUpdateRequest (required) + * @return OK (status code 200) + */ + @Operation( + operationId = "updateUser", + tags = {"user-controller"}, + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + }) + @RequestMapping( + method = RequestMethod.PATCH, + value = "/api/v1/users/{id}", + produces = {"*/*"}, + consumes = {"application/json"}) + default ResponseEntity updateUser( + @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id, + @Parameter(name = "UserUpdateRequest", description = "", required = true) @Valid @RequestBody + UserUpdateRequest userUpdateRequest) { + return getDelegate().updateUser(id, userUpdateRequest); + } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java index 4e66358aea..480851fe28 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java @@ -1,44 +1,24 @@ package org.sagebionetworks.challenge.api; -import org.sagebionetworks.challenge.model.dto.User; -import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; - - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.CookieValue; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.multipart.MultipartFile; - -import javax.validation.constraints.*; -import javax.validation.Valid; - -import java.util.List; -import java.util.Map; import java.util.Optional; import javax.annotation.Generated; +import javax.validation.constraints.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @Controller public class UserControllerApiController implements UserControllerApi { - private final UserControllerApiDelegate delegate; - - public UserControllerApiController(@Autowired(required = false) UserControllerApiDelegate delegate) { - this.delegate = Optional.ofNullable(delegate).orElse(new UserControllerApiDelegate() {}); - } + private final UserControllerApiDelegate delegate; - @Override - public UserControllerApiDelegate getDelegate() { - return delegate; - } + public UserControllerApiController( + @Autowired(required = false) UserControllerApiDelegate delegate) { + this.delegate = Optional.ofNullable(delegate).orElse(new UserControllerApiDelegate() {}); + } + @Override + public UserControllerApiDelegate getDelegate() { + return delegate; + } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java index 6d352b8944..8995263d9c 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java @@ -1,117 +1,119 @@ package org.sagebionetworks.challenge.api; +import java.util.List; +import java.util.Optional; +import javax.annotation.Generated; import org.sagebionetworks.challenge.model.dto.User; import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import javax.annotation.Generated; /** - * A delegate to be called by the {@link UserControllerApiController}}. - * Implement this interface with a {@link org.springframework.stereotype.Service} annotated class. + * A delegate to be called by the {@link UserControllerApiController}}. Implement this interface + * with a {@link org.springframework.stereotype.Service} annotated class. */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") public interface UserControllerApiDelegate { - default Optional getRequest() { - return Optional.empty(); - } + default Optional getRequest() { + return Optional.empty(); + } - /** - * POST /api/v1/users/register - * - * @param user (required) - * @return OK (status code 200) - * @see UserControllerApi#createUser - */ - default ResponseEntity createUser(User user) { - getRequest().ifPresent(request -> { - for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + /** + * POST /api/v1/users/register + * + * @param user (required) + * @return OK (status code 200) + * @see UserControllerApi#createUser + */ + default ResponseEntity createUser(User user) { + getRequest() + .ifPresent( + request -> { + for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) { if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { - String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); - break; + String exampleString = + "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; } - } - }); - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - - } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } - /** - * GET /api/v1/users/{id} - * - * @param id (required) - * @return OK (status code 200) - * @see UserControllerApi#getUser - */ - default ResponseEntity getUser(Long id) { - getRequest().ifPresent(request -> { - for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + /** + * GET /api/v1/users/{id} + * + * @param id (required) + * @return OK (status code 200) + * @see UserControllerApi#getUser + */ + default ResponseEntity getUser(Long id) { + getRequest() + .ifPresent( + request -> { + for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) { if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { - String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); - break; + String exampleString = + "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; } - } - }); - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - - } + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } - /** - * GET /api/v1/users/ - * - * @param page Zero-based page index (0..N) (optional, default to 0) - * @param size The size of the page to be returned (optional, default to 20) - * @param sort Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported. (optional) - * @return OK (status code 200) - * @see UserControllerApi#listUsers - */ - default ResponseEntity> listUsers(Integer page, - Integer size, - List sort) { - getRequest().ifPresent(request -> { - for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + /** + * GET /api/v1/users/ + * + * @param page Zero-based page index (0..N) (optional, default to 0) + * @param size The size of the page to be returned (optional, default to 20) + * @param sort Sorting criteria in the format: property,(asc|desc). Default sort order is + * ascending. Multiple sort criteria are supported. (optional) + * @return OK (status code 200) + * @see UserControllerApi#listUsers + */ + default ResponseEntity> listUsers(Integer page, Integer size, List sort) { + getRequest() + .ifPresent( + request -> { + for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) { if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { - String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); - break; + String exampleString = + "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; } - } - }); - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } - } - - /** - * PATCH /api/v1/users/{id} - * - * @param id (required) - * @param userUpdateRequest (required) - * @return OK (status code 200) - * @see UserControllerApi#updateUser - */ - default ResponseEntity updateUser(Long id, - UserUpdateRequest userUpdateRequest) { - getRequest().ifPresent(request -> { - for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) { + /** + * PATCH /api/v1/users/{id} + * + * @param id (required) + * @param userUpdateRequest (required) + * @return OK (status code 200) + * @see UserControllerApi#updateUser + */ + default ResponseEntity updateUser(Long id, UserUpdateRequest userUpdateRequest) { + getRequest() + .ifPresent( + request -> { + for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) { if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { - String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); - break; + String exampleString = + "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + ApiUtil.setExampleResponse(request, "*/*", exampleString); + break; } - } - }); - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); - - } - + } + }); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java index e581cfb2ca..531460baad 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java @@ -1,20 +1,14 @@ package org.sagebionetworks.challenge.configuration; -import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.GetMapping; -/** - * Home redirection to OpenAPI api documentation - */ +/** Home redirection to OpenAPI api documentation */ @Controller public class HomeController { - @RequestMapping("/") - public String index() { - return "redirect:swagger-ui.html"; - } - -} \ No newline at end of file + @RequestMapping("/") + public String index() { + return "redirect:swagger-ui.html"; + } +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java index 1af2712112..5c49757dd2 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java @@ -1,38 +1,30 @@ package org.sagebionetworks.challenge.configuration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; -import io.swagger.v3.oas.models.Components; -import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; @Configuration public class SpringDocConfiguration { - @Bean - OpenAPI apiInfo() { - return new OpenAPI() - .info( - new Info() - .title("User API") - .description("This is the User Service of the Challenge Registry.") - .termsOfService("TOC") - .contact( - new Contact() - .name("This is the User ") - .url("https://challenge-registry.org") - ) - .license( - new License() - .name("Apache 2.0") - .url("https://github.com/Sage-Bionetworks/challenge-registry/blob/main/LICENSE.txt") - ) - .version("v1.0") - ) - ; - } -} \ No newline at end of file + @Bean + OpenAPI apiInfo() { + return new OpenAPI() + .info( + new Info() + .title("User API") + .description("This is the User Service of the Challenge Registry.") + .termsOfService("TOC") + .contact( + new Contact().name("This is the User ").url("https://challenge-registry.org")) + .license( + new License() + .name("Apache 2.0") + .url( + "https://github.com/Sage-Bionetworks/challenge-registry/blob/main/LICENSE.txt")) + .version("v1.0")); + } +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java index fae0cab306..995685efc9 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java @@ -1,24 +1,15 @@ package org.sagebionetworks.challenge.model.dto; -import java.net.URI; -import java.util.Objects; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; -import org.openapitools.jackson.nullable.JsonNullable; -import java.time.OffsetDateTime; -import javax.validation.Valid; -import javax.validation.constraints.*; import io.swagger.v3.oas.annotations.media.Schema; - - import java.util.*; +import java.util.Objects; import javax.annotation.Generated; +import javax.validation.constraints.*; -/** - * User - */ - +/** User */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") public class User { @@ -37,16 +28,14 @@ public class User { @JsonProperty("authId") private String authId; - /** - * Gets or Sets status - */ + /** Gets or Sets status */ public enum StatusEnum { PENDING("PENDING"), - + APPROVED("APPROVED"), - + DISABLED("DISABLED"), - + BLACKLIST("BLACKLIST"); private String value; @@ -86,9 +75,9 @@ public User id(Long id) { /** * Get id + * * @return id - */ - + */ @Schema(name = "id", required = false) public Long getId() { return id; @@ -105,9 +94,9 @@ public User username(String username) { /** * Get username + * * @return username - */ - + */ @Schema(name = "username", required = false) public String getUsername() { return username; @@ -124,9 +113,9 @@ public User email(String email) { /** * Get email + * * @return email - */ - + */ @Schema(name = "email", required = false) public String getEmail() { return email; @@ -143,9 +132,9 @@ public User password(String password) { /** * Get password + * * @return password - */ - + */ @Schema(name = "password", required = false) public String getPassword() { return password; @@ -162,9 +151,9 @@ public User authId(String authId) { /** * Get authId + * * @return authId - */ - + */ @Schema(name = "authId", required = false) public String getAuthId() { return authId; @@ -181,9 +170,9 @@ public User status(StatusEnum status) { /** * Get status + * * @return status - */ - + */ @Schema(name = "status", required = false) public StatusEnum getStatus() { return status; @@ -202,12 +191,12 @@ public boolean equals(Object o) { return false; } User user = (User) o; - return Objects.equals(this.id, user.id) && - Objects.equals(this.username, user.username) && - Objects.equals(this.email, user.email) && - Objects.equals(this.password, user.password) && - Objects.equals(this.authId, user.authId) && - Objects.equals(this.status, user.status); + return Objects.equals(this.id, user.id) + && Objects.equals(this.username, user.username) + && Objects.equals(this.email, user.email) + && Objects.equals(this.password, user.password) + && Objects.equals(this.authId, user.authId) + && Objects.equals(this.status, user.status); } @Override @@ -230,8 +219,7 @@ public String toString() { } /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). + * Convert the given object to string with each line indented by 4 spaces (except the first line). */ private String toIndentedString(Object o) { if (o == null) { @@ -240,4 +228,3 @@ private String toIndentedString(Object o) { return o.toString().replace("\n", "\n "); } } - diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java index a3e77bf978..d136817eb2 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java @@ -1,37 +1,26 @@ package org.sagebionetworks.challenge.model.dto; -import java.net.URI; -import java.util.Objects; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; -import org.openapitools.jackson.nullable.JsonNullable; -import java.time.OffsetDateTime; -import javax.validation.Valid; -import javax.validation.constraints.*; import io.swagger.v3.oas.annotations.media.Schema; - - import java.util.*; +import java.util.Objects; import javax.annotation.Generated; +import javax.validation.constraints.*; -/** - * UserUpdateRequest - */ - +/** UserUpdateRequest */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") public class UserUpdateRequest { - /** - * Gets or Sets status - */ + /** Gets or Sets status */ public enum StatusEnum { PENDING("PENDING"), - + APPROVED("APPROVED"), - + DISABLED("DISABLED"), - + BLACKLIST("BLACKLIST"); private String value; @@ -71,9 +60,9 @@ public UserUpdateRequest status(StatusEnum status) { /** * Get status + * * @return status - */ - + */ @Schema(name = "status", required = false) public StatusEnum getStatus() { return status; @@ -110,8 +99,7 @@ public String toString() { } /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). + * Convert the given object to string with each line indented by 4 spaces (except the first line). */ private String toIndentedString(Object o) { if (o == null) { @@ -120,4 +108,3 @@ private String toIndentedString(Object o) { return o.toString().replace("\n", "\n "); } } - diff --git a/apps/challenge-user-service/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java b/apps/challenge-user-service/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java index ff541d93f9..9719f3aefb 100644 --- a/apps/challenge-user-service/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java +++ b/apps/challenge-user-service/src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java @@ -6,8 +6,6 @@ @SpringBootTest class OpenApiGeneratorApplicationTests { - @Test - void contextLoads() { - } - -} \ No newline at end of file + @Test + void contextLoads() {} +} From efb76340c1eadb39ad4f99a50c3507c36c8cea23 Mon Sep 17 00:00:00 2001 From: tschaffter Date: Tue, 20 Sep 2022 21:04:12 +0000 Subject: [PATCH 19/62] Move package version to `gradle.properties` --- apps/challenge-user-service/build.gradle | 12 ++---------- apps/challenge-user-service/gradle.properties | 6 ++++++ 2 files changed, 8 insertions(+), 10 deletions(-) create mode 100644 apps/challenge-user-service/gradle.properties diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index 79a85486c4..c6b550698c 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -1,15 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '2.7.3' - id 'com.diffplug.spotless' version '6.8.0' -} - -ext { - fasterxmlVersion = '2.13.4' - keycloakVersion = '18.0.0' - springBootVersion = '2.7.3' - springCloudVersion = '3.1.3' - springDataVersion = '2.7.2' + id 'org.springframework.boot' version "${springBootVersion}" + id 'com.diffplug.spotless' version "${spotlessVersion}" } repositories { diff --git a/apps/challenge-user-service/gradle.properties b/apps/challenge-user-service/gradle.properties new file mode 100644 index 0000000000..153dfdd14a --- /dev/null +++ b/apps/challenge-user-service/gradle.properties @@ -0,0 +1,6 @@ +fasterxmlVersion=2.13.4 +keycloakVersion=18.0.0 +spotlessVersion=6.8.0 +springBootVersion=2.7.3 +springCloudVersion=3.1.3 +springDataVersion=2.7.2 \ No newline at end of file From 2252e21f9b4e4969ed44a5d4887b50a373f9c1b8 Mon Sep 17 00:00:00 2001 From: tschaffter Date: Tue, 20 Sep 2022 21:07:32 +0000 Subject: [PATCH 20/62] Update to spotless 6.11.0 --- apps/challenge-user-service/gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/challenge-user-service/gradle.properties b/apps/challenge-user-service/gradle.properties index 153dfdd14a..a89ce40f9c 100644 --- a/apps/challenge-user-service/gradle.properties +++ b/apps/challenge-user-service/gradle.properties @@ -1,6 +1,6 @@ fasterxmlVersion=2.13.4 keycloakVersion=18.0.0 -spotlessVersion=6.8.0 +spotlessVersion=6.11.0 springBootVersion=2.7.3 springCloudVersion=3.1.3 springDataVersion=2.7.2 \ No newline at end of file From b373141fc0a51f25f53c770e03085dedb7211ef0 Mon Sep 17 00:00:00 2001 From: tschaffter Date: Tue, 20 Sep 2022 22:59:41 +0000 Subject: [PATCH 21/62] Remove server folder --- .../server/.openapi-generator-ignore | 23 ------ .../server/.openapi-generator/FILES | 16 ---- .../server/.openapi-generator/VERSION | 1 - apps/challenge-user-service/server/README.md | 21 ----- apps/challenge-user-service/server/pom.xml | 80 ------------------- 5 files changed, 141 deletions(-) delete mode 100644 apps/challenge-user-service/server/.openapi-generator-ignore delete mode 100644 apps/challenge-user-service/server/.openapi-generator/FILES delete mode 100644 apps/challenge-user-service/server/.openapi-generator/VERSION delete mode 100644 apps/challenge-user-service/server/README.md delete mode 100644 apps/challenge-user-service/server/pom.xml diff --git a/apps/challenge-user-service/server/.openapi-generator-ignore b/apps/challenge-user-service/server/.openapi-generator-ignore deleted file mode 100644 index 7484ee590a..0000000000 --- a/apps/challenge-user-service/server/.openapi-generator-ignore +++ /dev/null @@ -1,23 +0,0 @@ -# OpenAPI Generator Ignore -# Generated by openapi-generator https://github.com/openapitools/openapi-generator - -# Use this file to prevent files from being overwritten by the generator. -# The patterns follow closely to .gitignore or .dockerignore. - -# As an example, the C# client generator defines ApiClient.cs. -# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: -#ApiClient.cs - -# You can match any string of characters against a directory, file or extension with a single asterisk (*): -#foo/*/qux -# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux - -# You can recursively match patterns against a directory, file or extension with a double asterisk (**): -#foo/**/qux -# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux - -# You can also negate patterns with an exclamation (!). -# For example, you can ignore all files in a docs folder with the file extension .md: -#docs/*.md -# Then explicitly reverse the ignore rule for a single file: -#!docs/README.md diff --git a/apps/challenge-user-service/server/.openapi-generator/FILES b/apps/challenge-user-service/server/.openapi-generator/FILES deleted file mode 100644 index 9509212031..0000000000 --- a/apps/challenge-user-service/server/.openapi-generator/FILES +++ /dev/null @@ -1,16 +0,0 @@ -.openapi-generator-ignore -README.md -pom.xml -src/main/java/org/sagebionetworks/challenge/OpenApiGeneratorApplication.java -src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java -src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java -src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java -src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java -src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java -src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java -src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java -src/main/java/org/sagebionetworks/challenge/model/dto/User.java -src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java -src/main/resources/application.properties -src/main/resources/openapi.yaml -src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/server/.openapi-generator/VERSION b/apps/challenge-user-service/server/.openapi-generator/VERSION deleted file mode 100644 index 358e78e607..0000000000 --- a/apps/challenge-user-service/server/.openapi-generator/VERSION +++ /dev/null @@ -1 +0,0 @@ -6.1.0 \ No newline at end of file diff --git a/apps/challenge-user-service/server/README.md b/apps/challenge-user-service/server/README.md deleted file mode 100644 index 6a7407b2a6..0000000000 --- a/apps/challenge-user-service/server/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# OpenAPI generated server - -Spring Boot Server - -## Overview -This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. -By using the [OpenAPI-Spec](https://openapis.org), you can easily generate a server stub. -This is an example of building a OpenAPI-enabled server in Java using the SpringBoot framework. - - -The underlying library integrating OpenAPI to Spring Boot is [springdoc](https://springdoc.org). -Springdoc will generate an OpenAPI v3 specification based on the generated Controller and Model classes. -The specification is available to download using the following url: -http://localhost:8083/v3/api-docs/ - -Start your server as a simple java application - -You can view the api documentation in swagger-ui by pointing to -http://localhost:8083/swagger-ui.html - -Change default port value in application.properties \ No newline at end of file diff --git a/apps/challenge-user-service/server/pom.xml b/apps/challenge-user-service/server/pom.xml deleted file mode 100644 index 6ebfb6b83a..0000000000 --- a/apps/challenge-user-service/server/pom.xml +++ /dev/null @@ -1,80 +0,0 @@ - - 4.0.0 - org.openapitools - openapi-spring - jar - openapi-spring - v1.0 - - 1.8 - ${java.version} - ${java.version} - UTF-8 - 1.6.8 - 4.10.3 - - - org.springframework.boot - spring-boot-starter-parent - 2.7.0 - - - - src/main/java - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.data - spring-data-commons - - - - org.springdoc - springdoc-openapi-ui - ${springdoc.version} - - - - com.google.code.findbugs - jsr305 - 3.0.2 - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - - - org.openapitools - jackson-databind-nullable - 0.2.2 - - - - org.springframework.boot - spring-boot-starter-validation - - - com.fasterxml.jackson.core - jackson-databind - - - org.springframework.boot - spring-boot-starter-test - test - - - From 65f3ee516e175ce42bd929143aed9324b175e662 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 02:05:40 +0000 Subject: [PATCH 22/62] Use application.yml --- .../.openapi-generator-ignore | 9 ++- .../.openapi-generator/FILES | 1 - apps/challenge-user-service/project.json | 10 +-- .../src/main/resources/application.properties | 3 - .../src/main/resources/application.yml | 76 +++++++++++++++++++ ...V1.0.20210427174638__create_user_table.sql | 13 ++++ .../V1.0.20210427174721__temp_data.sql | 7 ++ 7 files changed, 108 insertions(+), 11 deletions(-) delete mode 100644 apps/challenge-user-service/src/main/resources/application.properties create mode 100644 apps/challenge-user-service/src/main/resources/application.yml create mode 100644 apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174638__create_user_table.sql create mode 100644 apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql diff --git a/apps/challenge-user-service/.openapi-generator-ignore b/apps/challenge-user-service/.openapi-generator-ignore index 01b32bd8a2..a55a527ce7 100644 --- a/apps/challenge-user-service/.openapi-generator-ignore +++ b/apps/challenge-user-service/.openapi-generator-ignore @@ -1,5 +1,10 @@ pom.xml README.md -# Ignore our Spring Boot application class -**/OpenApiGeneratorApplication.java \ No newline at end of file +**/application.properties +**/OpenApiGeneratorApplication.java + + \ No newline at end of file diff --git a/apps/challenge-user-service/.openapi-generator/FILES b/apps/challenge-user-service/.openapi-generator/FILES index 1c3a6bff11..5ed3cb24de 100644 --- a/apps/challenge-user-service/.openapi-generator/FILES +++ b/apps/challenge-user-service/.openapi-generator/FILES @@ -8,6 +8,5 @@ src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java src/main/java/org/sagebionetworks/challenge/model/dto/User.java src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java -src/main/resources/application.properties src/main/resources/openapi.yaml src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/project.json b/apps/challenge-user-service/project.json index 22d8da38b8..5c3b751117 100644 --- a/apps/challenge-user-service/project.json +++ b/apps/challenge-user-service/project.json @@ -100,10 +100,10 @@ }, "tags": ["type:service", "scope:backend"], "implicitDependencies": [ - "challenge-mariadb", - "challenge-keycloak", - "challenge-service-registry", - "challenge-api-gateway", - "shared-java-challenge-util" + // "challenge-mariadb", + // "challenge-keycloak", + // "challenge-service-registry", + // "challenge-api-gateway", + // "shared-java-challenge-util" ] } diff --git a/apps/challenge-user-service/src/main/resources/application.properties b/apps/challenge-user-service/src/main/resources/application.properties deleted file mode 100644 index 2dca10ed5c..0000000000 --- a/apps/challenge-user-service/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -server.port=8083 -spring.jackson.date-format=org.sagebionetworks.challenge.RFC3339DateFormat -spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false diff --git a/apps/challenge-user-service/src/main/resources/application.yml b/apps/challenge-user-service/src/main/resources/application.yml new file mode 100644 index 0000000000..d15604b7b1 --- /dev/null +++ b/apps/challenge-user-service/src/main/resources/application.yml @@ -0,0 +1,76 @@ +spring: + application: + name: challenge-user-service + # datasource: + # # url: jdbc:mysql://challenge-mariadb:3306/challenge + # url: ${db.url} + # # url: jdbc:h2:mem:challenge + # username: challenge_user_service + # password: changeme + # jpa: + # hibernate: + # ddl-auto: update + jackson: + date-format: org.sagebionetworks.challenge.RFC3339DateFormat + serialization: + WRITE_DATES_AS_TIMESTAMPS: false + +server: + port: 8083 + +# eureka: +# client: +# service-url: +# # defaultZone: ${service.registry.url} +# defaultZone: http://challenge-service-registry:8081/eureka +# instance: +# preferIpAddress: true + +# management: +# info: +# env: +# enabled: true +# endpoints: +# web: +# exposure: +# include: info + +# info: +# application: +# name: ${spring.application.name} + +# keycloak: +# realm: test +# resource: challenge-user-service +# credentials: +# secret: GFRau7cQTxhx19CUmSdrqrqrZ1pshjjB +# # auth-server-url: ${keycloak.url} +# auth-server-url: http://challenge-keycloak:8080 +# ssl-required: external +# use-resource-role-mappings: true +# bearer-only: true + +# app: +# config: +# keycloak: +# # server-url: ${keycloak.url} +# server-url: http://challenge-keycloak:8080 +# realm: test +# # TODO: Which client ID property is used? +# client-id: challenge-api-client +# clientId: challenge-api-client +# client-secret: mg2DrRcxHx19PIITibdOnbNEbJUKjGKb + +# springdoc: +# version: openapi_3_1 +# swagger-ui: +# path: /api/v1/api-docs/ui +# # url: /api/v1/api-docs/openapi.json +# api-docs: +# enabled: true +# path: /api/v1/api-docs/openapi.json +# packagesToScan: org.sagebionetworks.challenge.controller +# pathsToMatch: /** + +# example: +# firstProperty: "main" diff --git a/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174638__create_user_table.sql b/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174638__create_user_table.sql new file mode 100644 index 0000000000..61662f30d7 --- /dev/null +++ b/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174638__create_user_table.sql @@ -0,0 +1,13 @@ +-- challenge.challenge_user definition + +CREATE TABLE `challenge_user` +( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `auth_id` varchar(255) DEFAULT NULL, + `status` varchar(255) DEFAULT NULL, + `username` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +); + +-- KEY `FKk9w2ogq595jbe8r2due7vv3xr` (`account_id`), +-- CONSTRAINT `FKk9w2ogq595jbe8r2due7vv3xr` FOREIGN KEY (`account_id`) REFERENCES `banking_core_account` (`id`) \ No newline at end of file diff --git a/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql b/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql new file mode 100644 index 0000000000..1ec5e58149 --- /dev/null +++ b/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql @@ -0,0 +1,7 @@ +INSERT INTO challenge_user + (id, auth_id, status, username) +VALUES ('1', 'b9302586-876b-47e8-900c-2c09f161b888', 'PENDING', 'test'), + ('2', '3739ed0d-6da2-4d65-ba5a-223eb2dfe2b6', 'PENDING', 'tschaffter'), + ('3', '9f6abcb0-25aa-49d7-aa1b-5292c8f3e26a', 'PENDING', 'rrchai'), + ('4', '04b800f3-c431-4862-93c4-2bef14fc204d', 'PENDING', 'vpchung'), + ('5', '1212f921-6ab0-444f-a5ea-9dc154199a3c', 'PENDING', 'oakenshield'); \ No newline at end of file From e3eb019b513fb66112b67b0c003c1e15655b14ff Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 02:05:57 +0000 Subject: [PATCH 23/62] Add Flyway dependencies --- apps/challenge-user-service/build.gradle | 11 +++++++---- apps/challenge-user-service/gradle.properties | 4 +++- .../migration/V1.0.20210427174721__temp_data.sql | 14 +++++++------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index c6b550698c..a2879cc3f6 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -1,7 +1,8 @@ plugins { + id 'com.diffplug.spotless' version "${spotlessVersion}" id 'java' id 'org.springframework.boot' version "${springBootVersion}" - id 'com.diffplug.spotless' version "${spotlessVersion}" + id "io.spring.dependency-management" version "${springDependencyManagementVersion}" } repositories { @@ -10,12 +11,14 @@ repositories { } dependencies { - implementation "com.fasterxml.jackson.core:jackson-databind:${fasterxmlVersion}" - implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${fasterxmlVersion}" - implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${fasterxmlVersion}" implementation 'com.google.code.findbugs:jsr305:3.0.2' + implementation "org.flywaydb:flyway-core:${flywaydbVersion}" + implementation "org.flywaydb:flyway-mysql:${flywaydbVersion}" implementation 'org.openapitools:jackson-databind-nullable:0.2.2' implementation 'org.springdoc:springdoc-openapi-ui:1.6.8' + implementation "com.fasterxml.jackson.core:jackson-databind:${fasterxmlVersion}" + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${fasterxmlVersion}" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${fasterxmlVersion}" implementation "org.springframework.boot:spring-boot-starter-validation:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" implementation "org.springframework.data:spring-data-commons:${springDataVersion}" diff --git a/apps/challenge-user-service/gradle.properties b/apps/challenge-user-service/gradle.properties index a89ce40f9c..32e25e3cbe 100644 --- a/apps/challenge-user-service/gradle.properties +++ b/apps/challenge-user-service/gradle.properties @@ -1,6 +1,8 @@ fasterxmlVersion=2.13.4 +flywaydbVersion=9.3.0 keycloakVersion=18.0.0 spotlessVersion=6.11.0 springBootVersion=2.7.3 springCloudVersion=3.1.3 -springDataVersion=2.7.2 \ No newline at end of file +springDataVersion=2.7.2 +springDependencyManagementVersion=1.0.13.RELEASE \ No newline at end of file diff --git a/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql b/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql index 1ec5e58149..ef2766168f 100644 --- a/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql +++ b/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql @@ -1,7 +1,7 @@ -INSERT INTO challenge_user - (id, auth_id, status, username) -VALUES ('1', 'b9302586-876b-47e8-900c-2c09f161b888', 'PENDING', 'test'), - ('2', '3739ed0d-6da2-4d65-ba5a-223eb2dfe2b6', 'PENDING', 'tschaffter'), - ('3', '9f6abcb0-25aa-49d7-aa1b-5292c8f3e26a', 'PENDING', 'rrchai'), - ('4', '04b800f3-c431-4862-93c4-2bef14fc204d', 'PENDING', 'vpchung'), - ('5', '1212f921-6ab0-444f-a5ea-9dc154199a3c', 'PENDING', 'oakenshield'); \ No newline at end of file +-- INSERT INTO challenge_user +-- (id, auth_id, status, username) +-- VALUES ('1', 'b9302586-876b-47e8-900c-2c09f161b888', 'PENDING', 'test'), +-- ('2', '3739ed0d-6da2-4d65-ba5a-223eb2dfe2b6', 'PENDING', 'tschaffter'), +-- ('3', '9f6abcb0-25aa-49d7-aa1b-5292c8f3e26a', 'PENDING', 'rrchai'), +-- ('4', '04b800f3-c431-4862-93c4-2bef14fc204d', 'PENDING', 'vpchung'), +-- ('5', '1212f921-6ab0-444f-a5ea-9dc154199a3c', 'PENDING', 'oakenshield'); \ No newline at end of file From 324822f98b2e16df3628e97f442557bde7994b1c Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 02:20:14 +0000 Subject: [PATCH 24/62] Add exception package --- apps/challenge-user-service/build.gradle | 5 +++-- apps/challenge-user-service/gradle.properties | 1 + .../challenge/exception/GlobalErrorCode.java | 8 ++++++++ .../challenge/exception/InvalidEmailException.java | 9 +++++++++ .../challenge/exception/InvalidUserException.java | 9 +++++++++ .../exception/UserAlreadyRegisteredException.java | 9 +++++++++ 6 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/GlobalErrorCode.java create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidEmailException.java create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidUserException.java create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/UserAlreadyRegisteredException.java diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index a2879cc3f6..a127b30974 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -12,13 +12,14 @@ repositories { dependencies { implementation 'com.google.code.findbugs:jsr305:3.0.2' - implementation "org.flywaydb:flyway-core:${flywaydbVersion}" - implementation "org.flywaydb:flyway-mysql:${flywaydbVersion}" implementation 'org.openapitools:jackson-databind-nullable:0.2.2' implementation 'org.springdoc:springdoc-openapi-ui:1.6.8' implementation "com.fasterxml.jackson.core:jackson-databind:${fasterxmlVersion}" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${fasterxmlVersion}" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${fasterxmlVersion}" + implementation "org.flywaydb:flyway-core:${flywaydbVersion}" + implementation "org.flywaydb:flyway-mysql:${flywaydbVersion}" + implementation "org.sagebionetworks.challenge:challenge-util:${challengeVersion}" implementation "org.springframework.boot:spring-boot-starter-validation:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" implementation "org.springframework.data:spring-data-commons:${springDataVersion}" diff --git a/apps/challenge-user-service/gradle.properties b/apps/challenge-user-service/gradle.properties index 32e25e3cbe..c35b9c8524 100644 --- a/apps/challenge-user-service/gradle.properties +++ b/apps/challenge-user-service/gradle.properties @@ -1,3 +1,4 @@ +challengeVersion=0.0.1-SNAPSHOT fasterxmlVersion=2.13.4 flywaydbVersion=9.3.0 keycloakVersion=18.0.0 diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/GlobalErrorCode.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/GlobalErrorCode.java new file mode 100644 index 0000000000..2117179f51 --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/GlobalErrorCode.java @@ -0,0 +1,8 @@ +package org.sagebionetworks.challenge.exception; + +public class GlobalErrorCode { + public static final String ERROR_ENTITY_NOT_FOUND = "CHALLENGE-USER-SERVICE-1000"; + public static final String ERROR_USERNAME_REGISTERED = "CHALLENGE-USER-SERVICE-1001"; + public static final String ERROR_INVALID_EMAIL = "CHALLENGE-USER-SERVICE-1002"; + public static final String ERROR_INVALID_USER = "CHALLENGE-USER-SERVICE-1003"; +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidEmailException.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidEmailException.java new file mode 100644 index 0000000000..e73b8beb75 --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidEmailException.java @@ -0,0 +1,9 @@ +package org.sagebionetworks.challenge.exception; + +import org.sagebionetworks.challenge.util.exception.SimpleChallengeGlobalException; + +public class InvalidEmailException extends SimpleChallengeGlobalException { + public InvalidEmailException(String message, String code) { + super(message, code); + } +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidUserException.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidUserException.java new file mode 100644 index 0000000000..157ce8f52f --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/InvalidUserException.java @@ -0,0 +1,9 @@ +package org.sagebionetworks.challenge.exception; + +import org.sagebionetworks.challenge.util.exception.SimpleChallengeGlobalException; + +public class InvalidUserException extends SimpleChallengeGlobalException { + public InvalidUserException(String message, String code) { + super(message, code); + } +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/UserAlreadyRegisteredException.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/UserAlreadyRegisteredException.java new file mode 100644 index 0000000000..3d4efc41bf --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/exception/UserAlreadyRegisteredException.java @@ -0,0 +1,9 @@ +package org.sagebionetworks.challenge.exception; + +import org.sagebionetworks.challenge.util.exception.SimpleChallengeGlobalException; + +public class UserAlreadyRegisteredException extends SimpleChallengeGlobalException { + public UserAlreadyRegisteredException(String message, String code) { + super(message, code); + } +} From fa68d3f3e830b51ab00e2c358dcda0d112f018a8 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 03:24:24 +0000 Subject: [PATCH 25/62] Update openapi-generator-ignore --- .../.openapi-generator-ignore | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/challenge-user-service/.openapi-generator-ignore b/apps/challenge-user-service/.openapi-generator-ignore index a55a527ce7..85881a5126 100644 --- a/apps/challenge-user-service/.openapi-generator-ignore +++ b/apps/challenge-user-service/.openapi-generator-ignore @@ -1,6 +1,28 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +# ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +# foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +# foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +# docs/*.md +# Then explicitly reverse the ignore rule for a single file: +# !docs/README.md pom.xml README.md - **/application.properties **/OpenApiGeneratorApplication.java From de0454bbc1b60604c87486ffb547f6f76316e7df Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 20:24:32 +0000 Subject: [PATCH 26/62] Rename tag to User --- .../.openapi-generator/FILES | 7 ++-- apps/challenge-user-service/build.gradle | 3 ++ apps/challenge-user-service/gradle.properties | 1 + apps/challenge-user-service/openapi.yaml | 25 +++++++------ .../{UserControllerApi.java => UserApi.java} | 18 +++++----- ...Controller.java => UserApiController.java} | 11 +++--- ...rApiDelegate.java => UserApiDelegate.java} | 14 ++++---- .../configuration/SpringDocConfiguration.java | 8 +++-- .../challenge/model/entity/UserEntity.java | 36 +++++++++++++++++++ .../challenge/model/mapper/UserMapper.java | 26 ++++++++++++++ .../src/main/resources/openapi.yaml | 31 ++++++++-------- 11 files changed, 126 insertions(+), 54 deletions(-) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/{UserControllerApi.java => UserApi.java} (92%) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/{UserControllerApiController.java => UserApiController.java} (58%) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/{UserControllerApiDelegate.java => UserApiDelegate.java} (92%) create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java diff --git a/apps/challenge-user-service/.openapi-generator/FILES b/apps/challenge-user-service/.openapi-generator/FILES index 5ed3cb24de..8da252f399 100644 --- a/apps/challenge-user-service/.openapi-generator/FILES +++ b/apps/challenge-user-service/.openapi-generator/FILES @@ -1,9 +1,8 @@ AUTHORS.md -src/main/java/org/sagebionetworks/challenge/RFC3339DateFormat.java src/main/java/org/sagebionetworks/challenge/api/ApiUtil.java -src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java -src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java -src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java +src/main/java/org/sagebionetworks/challenge/api/UserApi.java +src/main/java/org/sagebionetworks/challenge/api/UserApiController.java +src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java src/main/java/org/sagebionetworks/challenge/model/dto/User.java diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index a127b30974..05166603f6 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -11,6 +11,8 @@ repositories { } dependencies { + annotationProcessor "org.projectlombok:lombok:${lombokVersion}" + compileOnly "org.projectlombok:lombok:${lombokVersion}" implementation 'com.google.code.findbugs:jsr305:3.0.2' implementation 'org.openapitools:jackson-databind-nullable:0.2.2' implementation 'org.springdoc:springdoc-openapi-ui:1.6.8' @@ -20,6 +22,7 @@ dependencies { implementation "org.flywaydb:flyway-core:${flywaydbVersion}" implementation "org.flywaydb:flyway-mysql:${flywaydbVersion}" implementation "org.sagebionetworks.challenge:challenge-util:${challengeVersion}" + implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-validation:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" implementation "org.springframework.data:spring-data-commons:${springDataVersion}" diff --git a/apps/challenge-user-service/gradle.properties b/apps/challenge-user-service/gradle.properties index c35b9c8524..8779883914 100644 --- a/apps/challenge-user-service/gradle.properties +++ b/apps/challenge-user-service/gradle.properties @@ -2,6 +2,7 @@ challengeVersion=0.0.1-SNAPSHOT fasterxmlVersion=2.13.4 flywaydbVersion=9.3.0 keycloakVersion=18.0.0 +lombokVersion=1.18.24 spotlessVersion=6.11.0 springBootVersion=2.7.3 springCloudVersion=3.1.3 diff --git a/apps/challenge-user-service/openapi.yaml b/apps/challenge-user-service/openapi.yaml index c1a643d8e9..9a3c1e9dd8 100644 --- a/apps/challenge-user-service/openapi.yaml +++ b/apps/challenge-user-service/openapi.yaml @@ -1,23 +1,26 @@ -openapi: 3.0.1 +openapi: 3.0.3 info: - title: User API + title: Challenge User API description: This is the User Service of the Challenge Registry. termsOfService: TOC contact: - name: 'This is the User ' - url: https://challenge-registry.org + name: The Challenge Registry Team + url: https://github.com/Sage-Bionetworks/challenge-registry license: name: Apache 2.0 url: https://github.com/Sage-Bionetworks/challenge-registry/blob/main/LICENSE.txt - version: v1.0 + version: 1.0.0 servers: -- url: http://localhost:8083 - description: Generated server url + - url: http://localhost:8083 + description: Local server url +tags: + - name: User + description: Operations about users paths: /api/v1/users/register: post: tags: - - user-controller + - User operationId: createUser requestBody: content: @@ -35,7 +38,7 @@ paths: /api/v1/users/{id}: get: tags: - - user-controller + - User operationId: getUser parameters: - name: id @@ -53,7 +56,7 @@ paths: $ref: '#/components/schemas/User' patch: tags: - - user-controller + - User operationId: updateUser parameters: - name: id @@ -78,7 +81,7 @@ paths: /api/v1/users/: get: tags: - - user-controller + - User operationId: listUsers parameters: - name: page diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java similarity index 92% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java index 6d8233ea11..f36d11b629 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApi.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java @@ -22,12 +22,12 @@ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @Validated -@Tag(name = "UserController", description = "the UserController API") -@RequestMapping("${openapi.user.base-path:}") -public interface UserControllerApi { +@Tag(name = "User", description = "Operations about users") +@RequestMapping("${openapi.challengeUser.base-path:}") +public interface UserApi { - default UserControllerApiDelegate getDelegate() { - return new UserControllerApiDelegate() {}; + default UserApiDelegate getDelegate() { + return new UserApiDelegate() {}; } /** @@ -38,7 +38,7 @@ default UserControllerApiDelegate getDelegate() { */ @Operation( operationId = "createUser", - tags = {"user-controller"}, + tags = {"User"}, responses = { @ApiResponse( responseCode = "200", @@ -63,7 +63,7 @@ default ResponseEntity createUser( */ @Operation( operationId = "getUser", - tags = {"user-controller"}, + tags = {"User"}, responses = { @ApiResponse( responseCode = "200", @@ -90,7 +90,7 @@ default ResponseEntity getUser( */ @Operation( operationId = "listUsers", - tags = {"user-controller"}, + tags = {"User"}, responses = { @ApiResponse( responseCode = "200", @@ -131,7 +131,7 @@ default ResponseEntity> listUsers( */ @Operation( operationId = "updateUser", - tags = {"user-controller"}, + tags = {"User"}, responses = { @ApiResponse( responseCode = "200", diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiController.java similarity index 58% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiController.java index 480851fe28..f82513704f 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiController.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiController.java @@ -8,17 +8,16 @@ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @Controller -public class UserControllerApiController implements UserControllerApi { +public class UserApiController implements UserApi { - private final UserControllerApiDelegate delegate; + private final UserApiDelegate delegate; - public UserControllerApiController( - @Autowired(required = false) UserControllerApiDelegate delegate) { - this.delegate = Optional.ofNullable(delegate).orElse(new UserControllerApiDelegate() {}); + public UserApiController(@Autowired(required = false) UserApiDelegate delegate) { + this.delegate = Optional.ofNullable(delegate).orElse(new UserApiDelegate() {}); } @Override - public UserControllerApiDelegate getDelegate() { + public UserApiDelegate getDelegate() { return delegate; } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java similarity index 92% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java index 8995263d9c..cb2e0cc98f 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserControllerApiDelegate.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java @@ -11,11 +11,11 @@ import org.springframework.web.context.request.NativeWebRequest; /** - * A delegate to be called by the {@link UserControllerApiController}}. Implement this interface - * with a {@link org.springframework.stereotype.Service} annotated class. + * A delegate to be called by the {@link UserApiController}}. Implement this interface with a {@link + * org.springframework.stereotype.Service} annotated class. */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public interface UserControllerApiDelegate { +public interface UserApiDelegate { default Optional getRequest() { return Optional.empty(); @@ -26,7 +26,7 @@ default Optional getRequest() { * * @param user (required) * @return OK (status code 200) - * @see UserControllerApi#createUser + * @see UserApi#createUser */ default ResponseEntity createUser(User user) { getRequest() @@ -49,7 +49,7 @@ default ResponseEntity createUser(User user) { * * @param id (required) * @return OK (status code 200) - * @see UserControllerApi#getUser + * @see UserApi#getUser */ default ResponseEntity getUser(Long id) { getRequest() @@ -75,7 +75,7 @@ default ResponseEntity getUser(Long id) { * @param sort Sorting criteria in the format: property,(asc|desc). Default sort order is * ascending. Multiple sort criteria are supported. (optional) * @return OK (status code 200) - * @see UserControllerApi#listUsers + * @see UserApi#listUsers */ default ResponseEntity> listUsers(Integer page, Integer size, List sort) { getRequest() @@ -99,7 +99,7 @@ default ResponseEntity> listUsers(Integer page, Integer size, List updateUser(Long id, UserUpdateRequest userUpdateRequest) { getRequest() diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java index 5c49757dd2..9a9b7a842e 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java @@ -15,16 +15,18 @@ OpenAPI apiInfo() { return new OpenAPI() .info( new Info() - .title("User API") + .title("Challenge User API") .description("This is the User Service of the Challenge Registry.") .termsOfService("TOC") .contact( - new Contact().name("This is the User ").url("https://challenge-registry.org")) + new Contact() + .name("The Challenge Registry Team") + .url("https://github.com/Sage-Bionetworks/challenge-registry")) .license( new License() .name("Apache 2.0") .url( "https://github.com/Sage-Bionetworks/challenge-registry/blob/main/LICENSE.txt")) - .version("v1.0")); + .version("1.0.0")); } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java new file mode 100644 index 0000000000..d2c08a3fb1 --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java @@ -0,0 +1,36 @@ +package org.sagebionetworks.challenge.model.entity; + +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.sagebionetworks.challenge.model.dto.UserStatus; + +@Getter +@Setter +@Entity +@Table(name = "challenge_user") +@NoArgsConstructor +public class UserEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String username; + private String authId; + + @Enumerated(EnumType.STRING) + private UserStatus status; + + public UserEntity(String username, String authId, UserStatus status) { + this.username = username; + this.authId = authId; + this.status = status; + } +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java new file mode 100644 index 0000000000..bd125d942e --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java @@ -0,0 +1,26 @@ +package org.sagebionetworks.challenge.model.mapper; + +import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.entity.UserEntity; +import org.sagebionetworks.challenge.util.model.mapper.BaseMapper; +import org.springframework.beans.BeanUtils; + +public class UserMapper extends BaseMapper { + @Override + public UserEntity convertToEntity(User dto, Object... args) { + UserEntity userEntity = new UserEntity(); + if (dto != null) { + BeanUtils.copyProperties(dto, userEntity); + } + return userEntity; + } + + @Override + public User convertToDto(UserEntity entity, Object... args) { + User user = new User(); + if (entity != null) { + BeanUtils.copyProperties(entity, user); + } + return user; + } +} diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index f039156564..32401967e4 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -1,18 +1,21 @@ -openapi: 3.0.1 +openapi: 3.0.3 info: contact: - name: 'This is the User ' - url: https://challenge-registry.org + name: The Challenge Registry Team + url: https://github.com/Sage-Bionetworks/challenge-registry description: This is the User Service of the Challenge Registry. license: name: Apache 2.0 url: https://github.com/Sage-Bionetworks/challenge-registry/blob/main/LICENSE.txt termsOfService: TOC - title: User API - version: v1.0 + title: Challenge User API + version: 1.0.0 servers: -- description: Generated server url +- description: Local server url url: http://localhost:8083 +tags: +- description: Operations about users + name: User paths: /api/v1/users/register: post: @@ -31,11 +34,11 @@ paths: $ref: '#/components/schemas/User' description: OK tags: - - user-controller + - User x-content-type: application/json x-accepts: '*/*' x-tags: - - tag: user-controller + - tag: User /api/v1/users/{id}: get: operationId: getUser @@ -56,10 +59,10 @@ paths: $ref: '#/components/schemas/User' description: OK tags: - - user-controller + - User x-accepts: '*/*' x-tags: - - tag: user-controller + - tag: User patch: operationId: updateUser parameters: @@ -85,11 +88,11 @@ paths: $ref: '#/components/schemas/User' description: OK tags: - - user-controller + - User x-content-type: application/json x-accepts: '*/*' x-tags: - - tag: user-controller + - tag: User /api/v1/users/: get: operationId: listUsers @@ -135,10 +138,10 @@ paths: type: array description: OK tags: - - user-controller + - User x-accepts: '*/*' x-tags: - - tag: user-controller + - tag: User components: schemas: User: From 2a68a3e4197e1aa09063e8e50698a30faad34109 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 20:36:17 +0000 Subject: [PATCH 27/62] UserStatus has its own class --- .../.openapi-generator/FILES | 1 + apps/challenge-user-service/openapi.yaml | 22 ++++----- .../challenge/model/dto/User.java | 49 +++---------------- .../challenge/model/dto/UserStatus.java | 45 +++++++++++++++++ .../model/dto/UserUpdateRequest.java | 49 +++---------------- .../src/main/resources/openapi.yaml | 22 ++++----- 6 files changed, 78 insertions(+), 110 deletions(-) create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java diff --git a/apps/challenge-user-service/.openapi-generator/FILES b/apps/challenge-user-service/.openapi-generator/FILES index 8da252f399..823cad3893 100644 --- a/apps/challenge-user-service/.openapi-generator/FILES +++ b/apps/challenge-user-service/.openapi-generator/FILES @@ -6,6 +6,7 @@ src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java src/main/java/org/sagebionetworks/challenge/model/dto/User.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java src/main/resources/openapi.yaml src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/openapi.yaml b/apps/challenge-user-service/openapi.yaml index 9a3c1e9dd8..a79753b6c8 100644 --- a/apps/challenge-user-service/openapi.yaml +++ b/apps/challenge-user-service/openapi.yaml @@ -135,19 +135,17 @@ components: authId: type: string status: - type: string - enum: - - PENDING - - APPROVED - - DISABLED - - BLACKLIST + $ref: '#/components/schemas/UserStatus' UserUpdateRequest: type: object properties: status: - type: string - enum: - - PENDING - - APPROVED - - DISABLED - - BLACKLIST + $ref: '#/components/schemas/UserStatus' + UserStatus: + type: string + enum: + - PENDING + - APPROVED + - DISABLED + - BLACKLIST + example: PENDING \ No newline at end of file diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java index 995685efc9..ff4f3ed303 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java @@ -1,12 +1,11 @@ package org.sagebionetworks.challenge.model.dto; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; import io.swagger.v3.oas.annotations.media.Schema; import java.util.*; import java.util.Objects; import javax.annotation.Generated; +import javax.validation.Valid; import javax.validation.constraints.*; /** User */ @@ -28,45 +27,8 @@ public class User { @JsonProperty("authId") private String authId; - /** Gets or Sets status */ - public enum StatusEnum { - PENDING("PENDING"), - - APPROVED("APPROVED"), - - DISABLED("DISABLED"), - - BLACKLIST("BLACKLIST"); - - private String value; - - StatusEnum(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - @JsonCreator - public static StatusEnum fromValue(String value) { - for (StatusEnum b : StatusEnum.values()) { - if (b.value.equals(value)) { - return b; - } - } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); - } - } - @JsonProperty("status") - private StatusEnum status; + private UserStatus status; public User id(Long id) { this.id = id; @@ -163,7 +125,7 @@ public void setAuthId(String authId) { this.authId = authId; } - public User status(StatusEnum status) { + public User status(UserStatus status) { this.status = status; return this; } @@ -173,12 +135,13 @@ public User status(StatusEnum status) { * * @return status */ + @Valid @Schema(name = "status", required = false) - public StatusEnum getStatus() { + public UserStatus getStatus() { return status; } - public void setStatus(StatusEnum status) { + public void setStatus(UserStatus status) { this.status = status; } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java new file mode 100644 index 0000000000..0d1c5af11b --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java @@ -0,0 +1,45 @@ +package org.sagebionetworks.challenge.model.dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.*; +import javax.annotation.Generated; +import javax.validation.constraints.*; + +/** Gets or Sets UserStatus */ +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +public enum UserStatus { + PENDING("PENDING"), + + APPROVED("APPROVED"), + + DISABLED("DISABLED"), + + BLACKLIST("BLACKLIST"); + + private String value; + + UserStatus(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static UserStatus fromValue(String value) { + for (UserStatus b : UserStatus.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java index d136817eb2..38011b6076 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java @@ -1,59 +1,21 @@ package org.sagebionetworks.challenge.model.dto; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; import io.swagger.v3.oas.annotations.media.Schema; import java.util.*; import java.util.Objects; import javax.annotation.Generated; +import javax.validation.Valid; import javax.validation.constraints.*; /** UserUpdateRequest */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") public class UserUpdateRequest { - /** Gets or Sets status */ - public enum StatusEnum { - PENDING("PENDING"), - - APPROVED("APPROVED"), - - DISABLED("DISABLED"), - - BLACKLIST("BLACKLIST"); - - private String value; - - StatusEnum(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - @JsonCreator - public static StatusEnum fromValue(String value) { - for (StatusEnum b : StatusEnum.values()) { - if (b.value.equals(value)) { - return b; - } - } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); - } - } - @JsonProperty("status") - private StatusEnum status; + private UserStatus status; - public UserUpdateRequest status(StatusEnum status) { + public UserUpdateRequest status(UserStatus status) { this.status = status; return this; } @@ -63,12 +25,13 @@ public UserUpdateRequest status(StatusEnum status) { * * @return status */ + @Valid @Schema(name = "status", required = false) - public StatusEnum getStatus() { + public UserStatus getStatus() { return status; } - public void setStatus(StatusEnum status) { + public void setStatus(UserStatus status) { this.status = status; } diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index 32401967e4..cd1d024e1f 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -165,22 +165,20 @@ components: authId: type: string status: - enum: - - PENDING - - APPROVED - - DISABLED - - BLACKLIST - type: string + $ref: '#/components/schemas/UserStatus' type: object UserUpdateRequest: example: status: PENDING properties: status: - enum: - - PENDING - - APPROVED - - DISABLED - - BLACKLIST - type: string + $ref: '#/components/schemas/UserStatus' type: object + UserStatus: + enum: + - PENDING + - APPROVED + - DISABLED + - BLACKLIST + example: PENDING + type: string From 3f20917dd7514637a4609774db81c855e0a1333b Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 20:47:19 +0000 Subject: [PATCH 28/62] Fix DB seeding with Flyway --- apps/challenge-user-service/build.gradle | 1 + .../src/main/resources/application.yml | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index 05166603f6..f06a97dbe2 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -26,6 +26,7 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-validation:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" implementation "org.springframework.data:spring-data-commons:${springDataVersion}" + runtimeOnly 'mysql:mysql-connector-java:8.0.30' testImplementation "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" } diff --git a/apps/challenge-user-service/src/main/resources/application.yml b/apps/challenge-user-service/src/main/resources/application.yml index d15604b7b1..7dfe139eed 100644 --- a/apps/challenge-user-service/src/main/resources/application.yml +++ b/apps/challenge-user-service/src/main/resources/application.yml @@ -1,15 +1,15 @@ spring: application: name: challenge-user-service - # datasource: - # # url: jdbc:mysql://challenge-mariadb:3306/challenge - # url: ${db.url} - # # url: jdbc:h2:mem:challenge - # username: challenge_user_service - # password: changeme - # jpa: - # hibernate: - # ddl-auto: update + datasource: + # url: jdbc:mysql://challenge-mariadb:3306/challenge + url: ${db.url} + # url: jdbc:h2:mem:challenge + username: challenge_user_service + password: changeme + jpa: + hibernate: + ddl-auto: update jackson: date-format: org.sagebionetworks.challenge.RFC3339DateFormat serialization: From 38ed3ec9037a4c180471815f2ea8c1c9d9f8c6e5 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 21:18:58 +0000 Subject: [PATCH 29/62] Add Flyway gradle plugin --- apps/challenge-user-service/build.gradle | 23 +++++++++++++++++++ .../playground.session.sql | 6 ++++- .../V1.0.20210427174721__temp_data.sql | 14 +++++------ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index f06a97dbe2..db4fef0ee2 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -1,8 +1,18 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath "org.flywaydb:flyway-mysql:${flywaydbVersion}" + } +} + plugins { id 'com.diffplug.spotless' version "${spotlessVersion}" id 'java' id 'org.springframework.boot' version "${springBootVersion}" id "io.spring.dependency-management" version "${springDependencyManagementVersion}" + id "org.flywaydb.flyway" version "${flywaydbVersion}" } repositories { @@ -28,6 +38,7 @@ dependencies { implementation "org.springframework.data:spring-data-commons:${springDataVersion}" runtimeOnly 'mysql:mysql-connector-java:8.0.30' testImplementation "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + } group = 'org.sagebionetworks.challenge' @@ -60,3 +71,15 @@ spotless { googleJavaFormat() } } + +flyway { + url = 'jdbc:mysql://challenge-mariadb:3306/challenge' + user = 'maria' + password = 'changeme' + // schemas = ['schema1', 'schema2', 'schema3'] + // placeholders = [ + // 'keyABC': 'valueXYZ', + // 'otherplaceholder': 'value123' + // ] +} + diff --git a/apps/challenge-user-service/playground.session.sql b/apps/challenge-user-service/playground.session.sql index 1ab346fc83..fa0971a1c6 100644 --- a/apps/challenge-user-service/playground.session.sql +++ b/apps/challenge-user-service/playground.session.sql @@ -8,4 +8,8 @@ DELETE FROM challenge_user WHERE id=1; -- @block delete all users -DELETE FROM challenge_user; \ No newline at end of file +DELETE FROM challenge_user; + +-- @block delete flyway schema history + +DELETE FROM flyway_schema_history; \ No newline at end of file diff --git a/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql b/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql index ef2766168f..1ec5e58149 100644 --- a/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql +++ b/apps/challenge-user-service/src/main/resources/db/migration/V1.0.20210427174721__temp_data.sql @@ -1,7 +1,7 @@ --- INSERT INTO challenge_user --- (id, auth_id, status, username) --- VALUES ('1', 'b9302586-876b-47e8-900c-2c09f161b888', 'PENDING', 'test'), --- ('2', '3739ed0d-6da2-4d65-ba5a-223eb2dfe2b6', 'PENDING', 'tschaffter'), --- ('3', '9f6abcb0-25aa-49d7-aa1b-5292c8f3e26a', 'PENDING', 'rrchai'), --- ('4', '04b800f3-c431-4862-93c4-2bef14fc204d', 'PENDING', 'vpchung'), --- ('5', '1212f921-6ab0-444f-a5ea-9dc154199a3c', 'PENDING', 'oakenshield'); \ No newline at end of file +INSERT INTO challenge_user + (id, auth_id, status, username) +VALUES ('1', 'b9302586-876b-47e8-900c-2c09f161b888', 'PENDING', 'test'), + ('2', '3739ed0d-6da2-4d65-ba5a-223eb2dfe2b6', 'PENDING', 'tschaffter'), + ('3', '9f6abcb0-25aa-49d7-aa1b-5292c8f3e26a', 'PENDING', 'rrchai'), + ('4', '04b800f3-c431-4862-93c4-2bef14fc204d', 'PENDING', 'vpchung'), + ('5', '1212f921-6ab0-444f-a5ea-9dc154199a3c', 'PENDING', 'oakenshield'); \ No newline at end of file From d659865c7deefafd8dce0d883b36f5e1a4d2b322 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 21:25:44 +0000 Subject: [PATCH 30/62] Fix table with flywaClean --- apps/challenge-user-service/build.gradle | 1 + apps/challenge-user-service/gradle.properties | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index db4fef0ee2..281bfeb693 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -76,6 +76,7 @@ flyway { url = 'jdbc:mysql://challenge-mariadb:3306/challenge' user = 'maria' password = 'changeme' + cleanDisabled = false // schemas = ['schema1', 'schema2', 'schema3'] // placeholders = [ // 'keyABC': 'valueXYZ', diff --git a/apps/challenge-user-service/gradle.properties b/apps/challenge-user-service/gradle.properties index 8779883914..6c0defcb83 100644 --- a/apps/challenge-user-service/gradle.properties +++ b/apps/challenge-user-service/gradle.properties @@ -1,6 +1,6 @@ challengeVersion=0.0.1-SNAPSHOT fasterxmlVersion=2.13.4 -flywaydbVersion=9.3.0 +flywaydbVersion=9.3.1 keycloakVersion=18.0.0 lombokVersion=1.18.24 spotlessVersion=6.11.0 From 6aa5f2e51c826c0f10a1cc49c24b95c4351bbb42 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 22:13:51 +0000 Subject: [PATCH 31/62] Rename project task to `openapi-generate` --- apps/challenge-user-service/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/challenge-user-service/project.json b/apps/challenge-user-service/project.json index 5c3b751117..2bdd90bd66 100644 --- a/apps/challenge-user-service/project.json +++ b/apps/challenge-user-service/project.json @@ -86,7 +86,7 @@ }, "dependsOn": ["^install"] }, - "generate-code": { + "openapi-generate": { "executor": "@nrwl/workspace:run-commands", "options": { "commands": [ From d02b17828c383218f36d7373b2585accf1a8c011 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Wed, 21 Sep 2022 22:46:06 +0000 Subject: [PATCH 32/62] Add `@lombok.Builder` to DTO classes --- apps/challenge-user-service/openapi.yaml | 2 + .../challenge/model/dto/User.java | 1 + .../src/main/resources/openapi.yaml | 2 + .../templates/pojo.mustache | 251 ++++++++++++++++++ 4 files changed, 256 insertions(+) create mode 100644 apps/challenge-user-service/templates/pojo.mustache diff --git a/apps/challenge-user-service/openapi.yaml b/apps/challenge-user-service/openapi.yaml index a79753b6c8..49feefbef2 100644 --- a/apps/challenge-user-service/openapi.yaml +++ b/apps/challenge-user-service/openapi.yaml @@ -136,6 +136,8 @@ components: type: string status: $ref: '#/components/schemas/UserStatus' + x-java-class-annotations: + - '@lombok.Builder' UserUpdateRequest: type: object properties: diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java index ff4f3ed303..b5c4b4a1a4 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java @@ -10,6 +10,7 @@ /** User */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +@lombok.Builder public class User { @JsonProperty("id") diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index cd1d024e1f..d0f44c124d 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -167,6 +167,8 @@ components: status: $ref: '#/components/schemas/UserStatus' type: object + x-java-class-annotations: + - '@lombok.Builder' UserUpdateRequest: example: status: PENDING diff --git a/apps/challenge-user-service/templates/pojo.mustache b/apps/challenge-user-service/templates/pojo.mustache new file mode 100644 index 0000000000..3882c9e369 --- /dev/null +++ b/apps/challenge-user-service/templates/pojo.mustache @@ -0,0 +1,251 @@ +/** + * {{description}}{{^description}}{{classname}}{{/description}} + */ +{{>additionalModelTypeAnnotations}} +{{#description}} +{{#swagger1AnnotationLibrary}} +@ApiModel(description = "{{{description}}}") +{{/swagger1AnnotationLibrary}} +{{#swagger2AnnotationLibrary}} +@Schema({{#name}}name = "{{name}}", {{/name}}description = "{{{description}}}") +{{/swagger2AnnotationLibrary}} +{{/description}} +{{#discriminator}} +{{>typeInfoAnnotation}} +{{/discriminator}} +{{#jackson}} +{{#isClassnameSanitized}} +@JsonTypeName("{{name}}") +{{/isClassnameSanitized}} +{{/jackson}} +{{#withXml}} +{{>xmlAnnotation}} +{{/withXml}} +{{>generatedAnnotation}} +{{#vendorExtensions.x-class-extra-annotation}} +{{{vendorExtensions.x-class-extra-annotation}}} +{{/vendorExtensions.x-class-extra-annotation}} +{{#vendorExtensions.x-java-class-annotations}} +{{.}} +{{/vendorExtensions.x-java-class-annotations}} +public class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}{{^parent}}{{#hateoas}} extends RepresentationModel<{{classname}}> {{/hateoas}}{{/parent}}{{#vendorExtensions.x-implements}}{{#-first}} implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { +{{#serializableModel}} + + private static final long serialVersionUID = 1L; +{{/serializableModel}} + {{#vars}} + + {{#isEnum}} + {{^isContainer}} +{{>enumClass}} + {{/isContainer}} + {{#isContainer}} + {{#mostInnerItems}} +{{>enumClass}} + {{/mostInnerItems}} + {{/isContainer}} + {{/isEnum}} + {{#jackson}} + @JsonProperty("{{baseName}}") + {{#withXml}} + @JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{.}}", {{/xmlNamespace}}localName = "{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}") + {{/withXml}} + {{/jackson}} + {{#gson}} + @SerializedName("{{baseName}}") + {{/gson}} + {{#vendorExtensions.x-field-extra-annotation}} + {{{vendorExtensions.x-field-extra-annotation}}} + {{/vendorExtensions.x-field-extra-annotation}} + {{#isContainer}} + {{#useBeanValidation}}@Valid{{/useBeanValidation}} + {{#openApiNullable}} + private {{>nullableDataType}} {{name}} = {{#isNullable}}JsonNullable.undefined(){{/isNullable}}{{^isNullable}}{{#required}}{{{defaultValue}}}{{/required}}{{^required}}null{{/required}}{{/isNullable}}; + {{/openApiNullable}} + {{^openApiNullable}} + private {{>nullableDataType}} {{name}} = {{#required}}{{{defaultValue}}}{{/required}}{{^required}}null{{/required}}; + {{/openApiNullable}} + {{/isContainer}} + {{^isContainer}} + {{#isDate}} + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) + {{/isDate}} + {{#isDateTime}} + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + {{/isDateTime}} + {{#openApiNullable}} + private {{>nullableDataType}} {{name}}{{#isNullable}} = JsonNullable.undefined(){{/isNullable}}{{^isNullable}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{/isNullable}}; + {{/openApiNullable}} + {{^openApiNullable}} + private {{>nullableDataType}} {{name}}{{#isNullable}} = null{{/isNullable}}{{^isNullable}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{/isNullable}}; + {{/openApiNullable}} + {{/isContainer}} + {{/vars}} + {{#vars}} + + {{! begin feature: fluent setter methods }} + public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) { + {{#openApiNullable}} + this.{{name}} = {{#isNullable}}JsonNullable.of({{name}}){{/isNullable}}{{^isNullable}}{{name}}{{/isNullable}}; + {{/openApiNullable}} + {{^openApiNullable}} + this.{{name}} = {{name}}; + {{/openApiNullable}} + return this; + } + {{#isArray}} + + public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) { + {{#openApiNullable}} + {{^required}} + if (this.{{name}} == null{{#isNullable}} || !this.{{name}}.isPresent(){{/isNullable}}) { + this.{{name}} = {{#isNullable}}JsonNullable.of({{{defaultValue}}}){{/isNullable}}{{^isNullable}}{{{defaultValue}}}{{/isNullable}}; + } + {{/required}} + this.{{name}}{{#isNullable}}.get(){{/isNullable}}.add({{name}}Item); + {{/openApiNullable}} + {{^openApiNullable}} + if (this.{{name}} == null) { + this.{{name}} = {{{defaultValue}}}; + } + this.{{name}}.add({{name}}Item); + {{/openApiNullable}} + return this; + } + {{/isArray}} + {{#isMap}} + + public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) { + {{^required}} + if (this.{{name}} == null) { + this.{{name}} = {{{defaultValue}}}; + } + {{/required}} + this.{{name}}.put(key, {{name}}Item); + return this; + } + {{/isMap}} + {{! end feature: fluent setter methods }} + {{! begin feature: getter and setter }} + + /** + {{#description}} + * {{{.}}} + {{/description}} + {{^description}} + * Get {{name}} + {{/description}} + {{#minimum}} + * minimum: {{.}} + {{/minimum}} + {{#maximum}} + * maximum: {{.}} + {{/maximum}} + * @return {{name}} + */ + {{#vendorExtensions.x-extra-annotation}} + {{{vendorExtensions.x-extra-annotation}}} + {{/vendorExtensions.x-extra-annotation}} + {{#useBeanValidation}} + {{>beanValidation}} + {{/useBeanValidation}} + {{#swagger2AnnotationLibrary}} + @Schema(name = "{{{baseName}}}", {{#isReadOnly}}accessMode = Schema.AccessMode.READ_ONLY, {{/isReadOnly}}{{#example}}example = "{{{.}}}", {{/example}}{{#description}}description = "{{{.}}}", {{/description}}required = {{{required}}}) + {{/swagger2AnnotationLibrary}} + {{#swagger1AnnotationLibrary}} + @ApiModelProperty({{#example}}example = "{{{.}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}{{#isReadOnly}}readOnly = {{{isReadOnly}}}, {{/isReadOnly}}value = "{{{description}}}") + {{/swagger1AnnotationLibrary}} + public {{>nullableDataType}} {{getter}}() { + return {{name}}; + } + + {{#vendorExtensions.x-setter-extra-annotation}} + {{{vendorExtensions.x-setter-extra-annotation}}} + {{/vendorExtensions.x-setter-extra-annotation}} + public void {{setter}}({{>nullableDataType}} {{name}}) { + this.{{name}} = {{name}}; + } + {{! end feature: getter and setter }} + {{/vars}} + {{#parentVars}} + + {{! begin feature: fluent setter methods for inherited properties }} + public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) { + super.{{setter}}({{name}}); + return this; + } + {{#isArray}} + + public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) { + super.add{{nameInCamelCase}}Item({{name}}Item); + return this; + } + {{/isArray}} + {{#isMap}} + + public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) { + super.put{{nameInCamelCase}}Item({{name}}Item); + return this; + } + {{/isMap}} + {{! end feature: fluent setter methods for inherited properties }} + {{/parentVars}} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + }{{#hasVars}} + {{classname}} {{classVarName}} = ({{classname}}) o; + return {{#vars}}{{#vendorExtensions.x-is-jackson-optional-nullable}}equalsNullable(this.{{name}}, {{classVarName}}.{{name}}){{/vendorExtensions.x-is-jackson-optional-nullable}}{{^vendorExtensions.x-is-jackson-optional-nullable}}{{#isByteArray}}Arrays{{/isByteArray}}{{^isByteArray}}Objects{{/isByteArray}}.equals(this.{{name}}, {{classVarName}}.{{name}}){{/vendorExtensions.x-is-jackson-optional-nullable}}{{^-last}} && + {{/-last}}{{/vars}}{{#parent}} && + super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}} + return true;{{/hasVars}} + } + {{#vendorExtensions.x-jackson-optional-nullable-helpers}} + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + {{/vendorExtensions.x-jackson-optional-nullable-helpers}} + + @Override + public int hashCode() { + return Objects.hash({{#vars}}{{#vendorExtensions.x-is-jackson-optional-nullable}}hashCodeNullable({{name}}){{/vendorExtensions.x-is-jackson-optional-nullable}}{{^vendorExtensions.x-is-jackson-optional-nullable}}{{^isByteArray}}{{name}}{{/isByteArray}}{{#isByteArray}}Arrays.hashCode({{name}}){{/isByteArray}}{{/vendorExtensions.x-is-jackson-optional-nullable}}{{^-last}}, {{/-last}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}}); + } + {{#vendorExtensions.x-jackson-optional-nullable-helpers}} + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + {{/vendorExtensions.x-jackson-optional-nullable-helpers}} + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class {{classname}} {\n"); + {{#parent}} + sb.append(" ").append(toIndentedString(super.toString())).append("\n"); + {{/parent}} + {{#vars}}sb.append(" {{name}}: ").append(toIndentedString({{name}})).append("\n"); + {{/vars}}sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} From c0c63e141e8ea403154735f22b13fb43fe854a27 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 22 Sep 2022 00:31:34 +0000 Subject: [PATCH 33/62] Add annotation `@lombok.Builder` to POJO --- apps/challenge-user-service/openapi.yaml | 2 ++ .../challenge/model/dto/UserUpdateRequest.java | 1 + apps/challenge-user-service/src/main/resources/openapi.yaml | 2 ++ apps/challenge-user-service/templates/pojo.mustache | 5 ++++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/challenge-user-service/openapi.yaml b/apps/challenge-user-service/openapi.yaml index 49feefbef2..3e6de20240 100644 --- a/apps/challenge-user-service/openapi.yaml +++ b/apps/challenge-user-service/openapi.yaml @@ -143,6 +143,8 @@ components: properties: status: $ref: '#/components/schemas/UserStatus' + x-java-class-annotations: + - '@lombok.Builder' UserStatus: type: string enum: diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java index 38011b6076..f059aaa8c2 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java @@ -10,6 +10,7 @@ /** UserUpdateRequest */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +@lombok.Builder public class UserUpdateRequest { @JsonProperty("status") diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index d0f44c124d..ad21d52b8d 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -176,6 +176,8 @@ components: status: $ref: '#/components/schemas/UserStatus' type: object + x-java-class-annotations: + - '@lombok.Builder' UserStatus: enum: - PENDING diff --git a/apps/challenge-user-service/templates/pojo.mustache b/apps/challenge-user-service/templates/pojo.mustache index 3882c9e369..03b58fe88a 100644 --- a/apps/challenge-user-service/templates/pojo.mustache +++ b/apps/challenge-user-service/templates/pojo.mustache @@ -26,7 +26,10 @@ {{{vendorExtensions.x-class-extra-annotation}}} {{/vendorExtensions.x-class-extra-annotation}} {{#vendorExtensions.x-java-class-annotations}} -{{.}} +{{{.}}} +{{/vendorExtensions.x-java-class-annotations}} +{{^vendorExtensions.x-java-class-annotations}} +// TODO Add x-java-class-annotations {{/vendorExtensions.x-java-class-annotations}} public class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}{{^parent}}{{#hateoas}} extends RepresentationModel<{{classname}}> {{/hateoas}}{{/parent}}{{#vendorExtensions.x-implements}}{{#-first}} implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { {{#serializableModel}} From 5f1560f361c0186a49825648815b5be331320bf1 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 22 Sep 2022 00:44:25 +0000 Subject: [PATCH 34/62] Add repository package --- apps/challenge-user-service/openapi.yaml | 4 ++++ .../java/org/sagebionetworks/challenge/model/dto/User.java | 2 ++ .../challenge/model/dto/UserUpdateRequest.java | 2 ++ .../challenge/model/repository/UserRepository.java | 6 ++++++ apps/challenge-user-service/src/main/resources/openapi.yaml | 4 ++++ 5 files changed, 18 insertions(+) create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/repository/UserRepository.java diff --git a/apps/challenge-user-service/openapi.yaml b/apps/challenge-user-service/openapi.yaml index 3e6de20240..4384fb7f46 100644 --- a/apps/challenge-user-service/openapi.yaml +++ b/apps/challenge-user-service/openapi.yaml @@ -137,14 +137,18 @@ components: status: $ref: '#/components/schemas/UserStatus' x-java-class-annotations: + - '@lombok.AllArgsConstructor' - '@lombok.Builder' + - '@lombok.NoArgsConstructor' UserUpdateRequest: type: object properties: status: $ref: '#/components/schemas/UserStatus' x-java-class-annotations: + - '@lombok.AllArgsConstructor' - '@lombok.Builder' + - '@lombok.NoArgsConstructor' UserStatus: type: string enum: diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java index b5c4b4a1a4..a78a21b060 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java @@ -10,7 +10,9 @@ /** User */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +@lombok.AllArgsConstructor @lombok.Builder +@lombok.NoArgsConstructor public class User { @JsonProperty("id") diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java index f059aaa8c2..0f8ddcc815 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java @@ -10,7 +10,9 @@ /** UserUpdateRequest */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +@lombok.AllArgsConstructor @lombok.Builder +@lombok.NoArgsConstructor public class UserUpdateRequest { @JsonProperty("status") diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/repository/UserRepository.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/repository/UserRepository.java new file mode 100644 index 0000000000..abdc24355d --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/repository/UserRepository.java @@ -0,0 +1,6 @@ +package org.sagebionetworks.challenge.model.repository; + +import org.sagebionetworks.challenge.model.entity.UserEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository {} diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index ad21d52b8d..b42e0ac622 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -168,7 +168,9 @@ components: $ref: '#/components/schemas/UserStatus' type: object x-java-class-annotations: + - '@lombok.AllArgsConstructor' - '@lombok.Builder' + - '@lombok.NoArgsConstructor' UserUpdateRequest: example: status: PENDING @@ -177,7 +179,9 @@ components: $ref: '#/components/schemas/UserStatus' type: object x-java-class-annotations: + - '@lombok.AllArgsConstructor' - '@lombok.Builder' + - '@lombok.NoArgsConstructor' UserStatus: enum: - PENDING From 372157979a0e66136361f8e032371b926695f3aa Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 22 Sep 2022 00:46:45 +0000 Subject: [PATCH 35/62] Add response models --- .../model/rest/response/AccountResponse.java | 13 +++++++++++++ .../model/rest/response/UserResponse.java | 15 +++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/AccountResponse.java create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/UserResponse.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/AccountResponse.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/AccountResponse.java new file mode 100644 index 0000000000..50b18f3ae5 --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/AccountResponse.java @@ -0,0 +1,13 @@ +package org.sagebionetworks.challenge.model.rest.response; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AccountResponse { + private String number; + private Integer id; + private String type; + private String status; +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/UserResponse.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/UserResponse.java new file mode 100644 index 0000000000..e4ffdff28b --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/rest/response/UserResponse.java @@ -0,0 +1,15 @@ +package org.sagebionetworks.challenge.model.rest.response; + +import java.util.List; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class UserResponse { + private String firstName; + private String lastName; + private List challengeAccounts; + private Integer id; + private String email; +} From 3f7b2428ed9888af3134d908d28b5d9d5bb6b3bd Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 22 Sep 2022 15:08:20 +0000 Subject: [PATCH 36/62] Add Keycloak configuration --- .gitignore | 1 + apps/challenge-user-service/build.gradle | 4 +- .../configuration/KeycloakConfiguration.java | 15 ++++++++ .../configuration/KeycloakManager.java | 36 ++++++++++++++++++ .../KeycloakManagerProperties.java | 16 ++++++++ .../src/main/resources/application.yml | 38 +++++++++---------- 6 files changed, 89 insertions(+), 21 deletions(-) create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakConfiguration.java create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManager.java create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManagerProperties.java diff --git a/.gitignore b/.gitignore index 45503ee52b..d40b579d51 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ !.yarn/sdks !.yarn/versions apps/challenge-user-service-2 +apps/challengebot2 # See http://help.github.com/ignore-files/ for more about ignoring files. .coveralls.yml diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index 281bfeb693..0b4d2cc960 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -31,6 +31,8 @@ dependencies { implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${fasterxmlVersion}" implementation "org.flywaydb:flyway-core:${flywaydbVersion}" implementation "org.flywaydb:flyway-mysql:${flywaydbVersion}" + implementation "org.keycloak:keycloak-admin-client:${keycloakVersion}" + implementation "org.keycloak:keycloak-spring-boot-starter:${keycloakVersion}" implementation "org.sagebionetworks.challenge:challenge-util:${challengeVersion}" implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-validation:${springBootVersion}" @@ -38,7 +40,7 @@ dependencies { implementation "org.springframework.data:spring-data-commons:${springDataVersion}" runtimeOnly 'mysql:mysql-connector-java:8.0.30' testImplementation "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" - + } group = 'org.sagebionetworks.challenge' diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakConfiguration.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakConfiguration.java new file mode 100644 index 0000000000..49a9c28fcb --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakConfiguration.java @@ -0,0 +1,15 @@ +package org.sagebionetworks.challenge.configuration; + +import org.keycloak.adapters.KeycloakConfigResolver; +import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class KeycloakConfiguration { + + @Bean + public KeycloakConfigResolver keycloakConfigResolver() { + return new KeycloakSpringBootConfigResolver(); + } +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManager.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManager.java new file mode 100644 index 0000000000..effd748c7c --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManager.java @@ -0,0 +1,36 @@ +package org.sagebionetworks.challenge.configuration; + +import lombok.extern.slf4j.Slf4j; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.KeycloakBuilder; +import org.keycloak.admin.client.resource.RealmResource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class KeycloakManager { + + @Autowired private KeycloakManagerProperties keycloakProperties; + + private static Keycloak keycloakInstance = null; + + public RealmResource getKeycloakInstanceWithRealm() { + return getInstance().realm(keycloakProperties.getRealm()); + } + + public Keycloak getInstance() { + if (keycloakInstance == null) { + log.info("KC SERVER URL: {}", keycloakProperties.getServerUrl()); + keycloakInstance = + KeycloakBuilder.builder() + .serverUrl(keycloakProperties.getServerUrl()) + .realm(keycloakProperties.getRealm()) + .grantType("client_credentials") + .clientId(keycloakProperties.getClientId()) + .clientSecret(keycloakProperties.getClientSecret()) + .build(); + } + return keycloakInstance; + } +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManagerProperties.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManagerProperties.java new file mode 100644 index 0000000000..9bd4344836 --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/KeycloakManagerProperties.java @@ -0,0 +1,16 @@ +package org.sagebionetworks.challenge.configuration; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Data +@Configuration +@ConfigurationProperties(prefix = "app.config.keycloak") +public class KeycloakManagerProperties { + + private String serverUrl; + private String realm; + private String clientId; + private String clientSecret; +} diff --git a/apps/challenge-user-service/src/main/resources/application.yml b/apps/challenge-user-service/src/main/resources/application.yml index 7dfe139eed..e4b4ad1d7d 100644 --- a/apps/challenge-user-service/src/main/resources/application.yml +++ b/apps/challenge-user-service/src/main/resources/application.yml @@ -39,27 +39,25 @@ server: # application: # name: ${spring.application.name} -# keycloak: -# realm: test -# resource: challenge-user-service -# credentials: -# secret: GFRau7cQTxhx19CUmSdrqrqrZ1pshjjB -# # auth-server-url: ${keycloak.url} -# auth-server-url: http://challenge-keycloak:8080 -# ssl-required: external -# use-resource-role-mappings: true -# bearer-only: true +keycloak: + realm: test + resource: challenge-user-service + credentials: + secret: GFRau7cQTxhx19CUmSdrqrqrZ1pshjjB + auth-server-url: ${keycloak.url} + ssl-required: external + use-resource-role-mappings: true + bearer-only: true -# app: -# config: -# keycloak: -# # server-url: ${keycloak.url} -# server-url: http://challenge-keycloak:8080 -# realm: test -# # TODO: Which client ID property is used? -# client-id: challenge-api-client -# clientId: challenge-api-client -# client-secret: mg2DrRcxHx19PIITibdOnbNEbJUKjGKb +app: + config: + keycloak: + server-url: ${keycloak.url} + realm: test + # TODO: Which client ID property is used? + client-id: challenge-api-client + clientId: challenge-api-client + client-secret: mg2DrRcxHx19PIITibdOnbNEbJUKjGKb # springdoc: # version: openapi_3_1 From ab4ecff5471ebf03ceed0adb2e5fd13e45f2790e Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 22 Sep 2022 15:10:49 +0000 Subject: [PATCH 37/62] Add KeycloakUserService --- .../service/KeycloakUserService.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/KeycloakUserService.java diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/KeycloakUserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/KeycloakUserService.java new file mode 100644 index 0000000000..4f2962855c --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/KeycloakUserService.java @@ -0,0 +1,45 @@ +package org.sagebionetworks.challenge.service; + +import java.util.Optional; +import javax.ws.rs.core.Response; +import org.keycloak.admin.client.resource.UserResource; +import org.keycloak.representations.idm.UserRepresentation; +import org.sagebionetworks.challenge.configuration.KeycloakManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class KeycloakUserService { + + @Autowired private KeycloakManager keycloakManager; + + public Integer createUser(UserRepresentation userRepresentation) { + Response response = + keycloakManager.getKeycloakInstanceWithRealm().users().create(userRepresentation); + return response.getStatus(); + } + + public void updateUser(UserRepresentation userRepresentation) { + keycloakManager + .getKeycloakInstanceWithRealm() + .users() + .get(userRepresentation.getId()) + .update(userRepresentation); + } + + public Optional getUserByUsername(String username) { + return keycloakManager.getKeycloakInstanceWithRealm().users().search(username).stream() + .filter(userRep -> username.equals(userRep.getUsername())) + .findFirst(); + } + + public UserRepresentation getUser(String authId) { + try { + UserResource userResource = + keycloakManager.getKeycloakInstanceWithRealm().users().get(authId); + return userResource.toRepresentation(); + } catch (Exception e) { + throw new RuntimeException("User not found under given ID"); + } + } +} From 1e9928c037b5120acc4084d34e7bc5264fc5aeed Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 22 Sep 2022 16:34:48 +0000 Subject: [PATCH 38/62] Add Dto suffix --- .../.openapi-generator/FILES | 6 +-- apps/challenge-user-service/openapitools.json | 1 + .../challenge/api/UserApi.java | 45 ++++++++++++------- .../challenge/api/UserApiDelegate.java | 16 +++---- .../model/dto/{User.java => UserDto.java} | 28 ++++++------ .../{UserStatus.java => UserStatusDto.java} | 8 ++-- ...Request.java => UserUpdateRequestDto.java} | 18 ++++---- .../challenge/model/entity/UserEntity.java | 6 +-- .../challenge/model/mapper/UserMapper.java | 10 ++--- .../src/main/resources/openapi.yaml | 2 - 10 files changed, 77 insertions(+), 63 deletions(-) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/{User.java => UserDto.java} (87%) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/{UserStatus.java => UserStatusDto.java} (82%) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/{UserUpdateRequest.java => UserUpdateRequestDto.java} (76%) diff --git a/apps/challenge-user-service/.openapi-generator/FILES b/apps/challenge-user-service/.openapi-generator/FILES index 823cad3893..ffa03dc705 100644 --- a/apps/challenge-user-service/.openapi-generator/FILES +++ b/apps/challenge-user-service/.openapi-generator/FILES @@ -5,8 +5,8 @@ src/main/java/org/sagebionetworks/challenge/api/UserApiController.java src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java -src/main/java/org/sagebionetworks/challenge/model/dto/User.java -src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java -src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java src/main/resources/openapi.yaml src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index 152a6b6d47..fd466f92ba 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -16,6 +16,7 @@ "configPackage": "org.sagebionetworks.challenge.configuration", "delegatePattern": true, "hideGenerationTimestamp": true, + "modelNameSuffix": "Dto", "modelPackage": "org.sagebionetworks.challenge.model.dto", "useTags": true } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java index f36d11b629..4629f8575f 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java @@ -14,8 +14,8 @@ import javax.annotation.Generated; import javax.validation.Valid; import javax.validation.constraints.*; -import org.sagebionetworks.challenge.model.dto.User; -import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; +import org.sagebionetworks.challenge.model.dto.UserDto; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequestDto; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -33,7 +33,7 @@ default UserApiDelegate getDelegate() { /** * POST /api/v1/users/register * - * @param user (required) + * @param userDto (required) * @return OK (status code 200) */ @Operation( @@ -43,16 +43,19 @@ default UserApiDelegate getDelegate() { @ApiResponse( responseCode = "200", description = "OK", - content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + }) }) @RequestMapping( method = RequestMethod.POST, value = "/api/v1/users/register", produces = {"*/*"}, consumes = {"application/json"}) - default ResponseEntity createUser( - @Parameter(name = "User", description = "", required = true) @Valid @RequestBody User user) { - return getDelegate().createUser(user); + default ResponseEntity createUser( + @Parameter(name = "UserDto", description = "", required = true) @Valid @RequestBody + UserDto userDto) { + return getDelegate().createUser(userDto); } /** @@ -68,13 +71,15 @@ default ResponseEntity createUser( @ApiResponse( responseCode = "200", description = "OK", - content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + }) }) @RequestMapping( method = RequestMethod.GET, value = "/api/v1/users/{id}", produces = {"*/*"}) - default ResponseEntity getUser( + default ResponseEntity getUser( @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id) { return getDelegate().getUser(id); } @@ -95,13 +100,15 @@ default ResponseEntity getUser( @ApiResponse( responseCode = "200", description = "OK", - content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + }) }) @RequestMapping( method = RequestMethod.GET, value = "/api/v1/users/", produces = {"*/*"}) - default ResponseEntity> listUsers( + default ResponseEntity> listUsers( @Min(0) @Parameter(name = "page", description = "Zero-based page index (0..N)") @Valid @@ -126,7 +133,7 @@ default ResponseEntity> listUsers( * PATCH /api/v1/users/{id} * * @param id (required) - * @param userUpdateRequest (required) + * @param userUpdateRequestDto (required) * @return OK (status code 200) */ @Operation( @@ -136,17 +143,21 @@ default ResponseEntity> listUsers( @ApiResponse( responseCode = "200", description = "OK", - content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + }) }) @RequestMapping( method = RequestMethod.PATCH, value = "/api/v1/users/{id}", produces = {"*/*"}, consumes = {"application/json"}) - default ResponseEntity updateUser( + default ResponseEntity updateUser( @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id, - @Parameter(name = "UserUpdateRequest", description = "", required = true) @Valid @RequestBody - UserUpdateRequest userUpdateRequest) { - return getDelegate().updateUser(id, userUpdateRequest); + @Parameter(name = "UserUpdateRequestDto", description = "", required = true) + @Valid + @RequestBody + UserUpdateRequestDto userUpdateRequestDto) { + return getDelegate().updateUser(id, userUpdateRequestDto); } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java index cb2e0cc98f..4af10580ac 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java @@ -3,8 +3,8 @@ import java.util.List; import java.util.Optional; import javax.annotation.Generated; -import org.sagebionetworks.challenge.model.dto.User; -import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; +import org.sagebionetworks.challenge.model.dto.UserDto; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequestDto; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -24,11 +24,11 @@ default Optional getRequest() { /** * POST /api/v1/users/register * - * @param user (required) + * @param userDto (required) * @return OK (status code 200) * @see UserApi#createUser */ - default ResponseEntity createUser(User user) { + default ResponseEntity createUser(UserDto userDto) { getRequest() .ifPresent( request -> { @@ -51,7 +51,7 @@ default ResponseEntity createUser(User user) { * @return OK (status code 200) * @see UserApi#getUser */ - default ResponseEntity getUser(Long id) { + default ResponseEntity getUser(Long id) { getRequest() .ifPresent( request -> { @@ -77,7 +77,7 @@ default ResponseEntity getUser(Long id) { * @return OK (status code 200) * @see UserApi#listUsers */ - default ResponseEntity> listUsers(Integer page, Integer size, List sort) { + default ResponseEntity> listUsers(Integer page, Integer size, List sort) { getRequest() .ifPresent( request -> { @@ -97,11 +97,11 @@ default ResponseEntity> listUsers(Integer page, Integer size, List updateUser(Long id, UserUpdateRequest userUpdateRequest) { + default ResponseEntity updateUser(Long id, UserUpdateRequestDto userUpdateRequestDto) { getRequest() .ifPresent( request -> { diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java similarity index 87% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java index a78a21b060..708aeb0c8f 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java @@ -1,6 +1,7 @@ package org.sagebionetworks.challenge.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; import io.swagger.v3.oas.annotations.media.Schema; import java.util.*; import java.util.Objects; @@ -8,12 +9,13 @@ import javax.validation.Valid; import javax.validation.constraints.*; -/** User */ +/** UserDto */ +@JsonTypeName("User") @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @lombok.AllArgsConstructor @lombok.Builder @lombok.NoArgsConstructor -public class User { +public class UserDto { @JsonProperty("id") private Long id; @@ -31,9 +33,9 @@ public class User { private String authId; @JsonProperty("status") - private UserStatus status; + private UserStatusDto status; - public User id(Long id) { + public UserDto id(Long id) { this.id = id; return this; } @@ -52,7 +54,7 @@ public void setId(Long id) { this.id = id; } - public User username(String username) { + public UserDto username(String username) { this.username = username; return this; } @@ -71,7 +73,7 @@ public void setUsername(String username) { this.username = username; } - public User email(String email) { + public UserDto email(String email) { this.email = email; return this; } @@ -90,7 +92,7 @@ public void setEmail(String email) { this.email = email; } - public User password(String password) { + public UserDto password(String password) { this.password = password; return this; } @@ -109,7 +111,7 @@ public void setPassword(String password) { this.password = password; } - public User authId(String authId) { + public UserDto authId(String authId) { this.authId = authId; return this; } @@ -128,7 +130,7 @@ public void setAuthId(String authId) { this.authId = authId; } - public User status(UserStatus status) { + public UserDto status(UserStatusDto status) { this.status = status; return this; } @@ -140,11 +142,11 @@ public User status(UserStatus status) { */ @Valid @Schema(name = "status", required = false) - public UserStatus getStatus() { + public UserStatusDto getStatus() { return status; } - public void setStatus(UserStatus status) { + public void setStatus(UserStatusDto status) { this.status = status; } @@ -156,7 +158,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - User user = (User) o; + UserDto user = (UserDto) o; return Objects.equals(this.id, user.id) && Objects.equals(this.username, user.username) && Objects.equals(this.email, user.email) @@ -173,7 +175,7 @@ public int hashCode() { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("class User {\n"); + sb.append("class UserDto {\n"); sb.append(" id: ").append(toIndentedString(id)).append("\n"); sb.append(" username: ").append(toIndentedString(username)).append("\n"); sb.append(" email: ").append(toIndentedString(email)).append("\n"); diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java similarity index 82% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java index 0d1c5af11b..c0fc7fe505 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java @@ -8,7 +8,7 @@ /** Gets or Sets UserStatus */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public enum UserStatus { +public enum UserStatusDto { PENDING("PENDING"), APPROVED("APPROVED"), @@ -19,7 +19,7 @@ public enum UserStatus { private String value; - UserStatus(String value) { + UserStatusDto(String value) { this.value = value; } @@ -34,8 +34,8 @@ public String toString() { } @JsonCreator - public static UserStatus fromValue(String value) { - for (UserStatus b : UserStatus.values()) { + public static UserStatusDto fromValue(String value) { + for (UserStatusDto b : UserStatusDto.values()) { if (b.value.equals(value)) { return b; } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java similarity index 76% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java index 0f8ddcc815..83e512ccb7 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java @@ -1,6 +1,7 @@ package org.sagebionetworks.challenge.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; import io.swagger.v3.oas.annotations.media.Schema; import java.util.*; import java.util.Objects; @@ -8,17 +9,18 @@ import javax.validation.Valid; import javax.validation.constraints.*; -/** UserUpdateRequest */ +/** UserUpdateRequestDto */ +@JsonTypeName("UserUpdateRequest") @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @lombok.AllArgsConstructor @lombok.Builder @lombok.NoArgsConstructor -public class UserUpdateRequest { +public class UserUpdateRequestDto { @JsonProperty("status") - private UserStatus status; + private UserStatusDto status; - public UserUpdateRequest status(UserStatus status) { + public UserUpdateRequestDto status(UserStatusDto status) { this.status = status; return this; } @@ -30,11 +32,11 @@ public UserUpdateRequest status(UserStatus status) { */ @Valid @Schema(name = "status", required = false) - public UserStatus getStatus() { + public UserStatusDto getStatus() { return status; } - public void setStatus(UserStatus status) { + public void setStatus(UserStatusDto status) { this.status = status; } @@ -46,7 +48,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - UserUpdateRequest userUpdateRequest = (UserUpdateRequest) o; + UserUpdateRequestDto userUpdateRequest = (UserUpdateRequestDto) o; return Objects.equals(this.status, userUpdateRequest.status); } @@ -58,7 +60,7 @@ public int hashCode() { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("class UserUpdateRequest {\n"); + sb.append("class UserUpdateRequestDto {\n"); sb.append(" status: ").append(toIndentedString(status)).append("\n"); sb.append("}"); return sb.toString(); diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java index d2c08a3fb1..00b30d65c4 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java @@ -10,7 +10,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import org.sagebionetworks.challenge.model.dto.UserStatus; +import org.sagebionetworks.challenge.model.dto.UserStatusDto; @Getter @Setter @@ -26,9 +26,9 @@ public class UserEntity { private String authId; @Enumerated(EnumType.STRING) - private UserStatus status; + private UserStatusDto status; - public UserEntity(String username, String authId, UserStatus status) { + public UserEntity(String username, String authId, UserStatusDto status) { this.username = username; this.authId = authId; this.status = status; diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java index bd125d942e..2b8bb930c8 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java @@ -1,13 +1,13 @@ package org.sagebionetworks.challenge.model.mapper; -import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.dto.UserDto; import org.sagebionetworks.challenge.model.entity.UserEntity; import org.sagebionetworks.challenge.util.model.mapper.BaseMapper; import org.springframework.beans.BeanUtils; -public class UserMapper extends BaseMapper { +public class UserMapper extends BaseMapper { @Override - public UserEntity convertToEntity(User dto, Object... args) { + public UserEntity convertToEntity(UserDto dto, Object... args) { UserEntity userEntity = new UserEntity(); if (dto != null) { BeanUtils.copyProperties(dto, userEntity); @@ -16,8 +16,8 @@ public UserEntity convertToEntity(User dto, Object... args) { } @Override - public User convertToDto(UserEntity entity, Object... args) { - User user = new User(); + public UserDto convertToDto(UserEntity entity, Object... args) { + UserDto user = new UserDto(); if (entity != null) { BeanUtils.copyProperties(entity, user); } diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index b42e0ac622..74a4e8dae0 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -172,8 +172,6 @@ components: - '@lombok.Builder' - '@lombok.NoArgsConstructor' UserUpdateRequest: - example: - status: PENDING properties: status: $ref: '#/components/schemas/UserStatus' From df2d0bb836bd2017834a51de13d43dda5df93e27 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 22 Sep 2022 16:36:36 +0000 Subject: [PATCH 39/62] Set library to `spring-boot` --- apps/challenge-user-service/openapitools.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index fd466f92ba..abb2d80d46 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -16,6 +16,7 @@ "configPackage": "org.sagebionetworks.challenge.configuration", "delegatePattern": true, "hideGenerationTimestamp": true, + "library": "spring-boot", "modelNameSuffix": "Dto", "modelPackage": "org.sagebionetworks.challenge.model.dto", "useTags": true From 36315a98a8511a04e20816f1e48f5ad982bc9f40 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 22 Sep 2022 17:43:33 +0000 Subject: [PATCH 40/62] Restore hot reload for spring app --- apps/challenge-user-service/build.gradle | 1 + .../challenge/api/UserApiDelegateImpl.java | 33 +++++++ .../challenge/service/UserService.java | 97 +++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index 0b4d2cc960..140a18084b 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -34,6 +34,7 @@ dependencies { implementation "org.keycloak:keycloak-admin-client:${keycloakVersion}" implementation "org.keycloak:keycloak-spring-boot-starter:${keycloakVersion}" implementation "org.sagebionetworks.challenge:challenge-util:${challengeVersion}" + implementation "org.springframework.boot:spring-boot-devtools:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-validation:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java new file mode 100644 index 0000000000..963fee04d3 --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -0,0 +1,33 @@ +package org.sagebionetworks.challenge.api; + +import org.sagebionetworks.challenge.model.dto.UserDto; +import org.sagebionetworks.challenge.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; + +@Component +public class UserApiDelegateImpl implements UserApiDelegate { + + @Autowired UserService userService; + + @Override + public ResponseEntity createUser(UserDto userDto) { + // getRequest() + // .ifPresent( + // request -> { + // for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) + // { + // if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + // String exampleString = + // "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", + // \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; + // ApiUtil.setExampleResponse(request, "*/*", exampleString); + // break; + // } + // } + // }); + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } +} diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java new file mode 100644 index 0000000000..c5177781ae --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java @@ -0,0 +1,97 @@ +package org.sagebionetworks.challenge.service; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import javax.persistence.EntityNotFoundException; +import lombok.extern.slf4j.Slf4j; +import org.keycloak.representations.idm.CredentialRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.sagebionetworks.challenge.exception.GlobalErrorCode; +import org.sagebionetworks.challenge.exception.InvalidUserException; +import org.sagebionetworks.challenge.exception.UserAlreadyRegisteredException; +import org.sagebionetworks.challenge.model.dto.UserDto; +import org.sagebionetworks.challenge.model.dto.UserStatusDto; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequestDto; +import org.sagebionetworks.challenge.model.entity.UserEntity; +import org.sagebionetworks.challenge.model.mapper.UserMapper; +import org.sagebionetworks.challenge.model.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +@Slf4j +// @RequiredArgsConstructor +@Service +public class UserService { + + @Autowired private KeycloakUserService keycloakUserService; + + @Autowired private UserRepository userRepository; + + private UserMapper userMapper = new UserMapper(); + + public UserDto createUser(UserDto user) { + if (keycloakUserService.getUserByUsername(user.getUsername()).isPresent()) { + throw new UserAlreadyRegisteredException( + "This username is already registered.", GlobalErrorCode.ERROR_USERNAME_REGISTERED); + } + + UserRepresentation userRepresentation = new UserRepresentation(); + userRepresentation.setEmail(user.getEmail()); + userRepresentation.setEmailVerified(false); + userRepresentation.setEnabled(true); + userRepresentation.setUsername(user.getUsername()); + + CredentialRepresentation credentialRepresentation = new CredentialRepresentation(); + credentialRepresentation.setValue(user.getPassword()); + credentialRepresentation.setTemporary(false); + userRepresentation.setCredentials(Collections.singletonList(credentialRepresentation)); + + Integer userCreationResponse = keycloakUserService.createUser(userRepresentation); + + if (userCreationResponse == 201) { + Optional representation = + keycloakUserService.getUserByUsername(user.getUsername()); + user.setAuthId(representation.get().getId()); + user.setStatus(UserStatusDto.PENDING); + UserEntity userEntity = userRepository.save(userMapper.convertToEntity(user)); + return userMapper.convertToDto(userEntity); + } + + throw new InvalidUserException( + "Unable to create the new user", GlobalErrorCode.ERROR_INVALID_USER); + } + + public List listUsers(Pageable pageable) { + Page allUsersInDb = userRepository.findAll(pageable); + List users = userMapper.convertToDtoList(allUsersInDb.getContent()); + users.forEach( + user -> { + UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); + user.setId(user.getId()); + user.setEmail(userRepresentation.getEmail()); + }); + return users; + } + + public UserDto getUser(Long userId) { + return userMapper.convertToDto( + userRepository.findById(userId).orElseThrow(EntityNotFoundException::new)); + } + + public UserDto updateUser(Long id, UserUpdateRequestDto userUpdateRequest) { + UserEntity userEntity = userRepository.findById(id).orElseThrow(EntityNotFoundException::new); + + if (userUpdateRequest.getStatus() == UserStatusDto.APPROVED) { + UserRepresentation userRepresentation = keycloakUserService.getUser(userEntity.getAuthId()); + userRepresentation.setEnabled(true); + userRepresentation.setEmailVerified(true); + keycloakUserService.updateUser(userRepresentation); + } + + userEntity.setStatus(userUpdateRequest.getStatus()); + return userMapper.convertToDto(userRepository.save(userEntity)); + } +} From 2e8888d79fb2a55b6728f9232ea80c9a7faf817f Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 22 Sep 2022 17:50:03 +0000 Subject: [PATCH 41/62] Remove Dto model suffix to increase user-friendliness --- .../.openapi-generator/FILES | 6 +-- apps/challenge-user-service/openapitools.json | 1 - .../challenge/api/UserApi.java | 45 +++++++------------ .../challenge/api/UserApiDelegate.java | 16 +++---- .../challenge/api/UserApiDelegateImpl.java | 4 +- .../model/dto/{UserDto.java => User.java} | 28 ++++++------ .../{UserStatusDto.java => UserStatus.java} | 8 ++-- ...RequestDto.java => UserUpdateRequest.java} | 18 ++++---- .../challenge/model/entity/UserEntity.java | 6 +-- .../challenge/model/mapper/UserMapper.java | 10 ++--- .../challenge/service/UserService.java | 20 ++++----- .../src/main/resources/openapi.yaml | 2 + 12 files changed, 75 insertions(+), 89 deletions(-) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/{UserDto.java => User.java} (87%) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/{UserStatusDto.java => UserStatus.java} (82%) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/{UserUpdateRequestDto.java => UserUpdateRequest.java} (76%) diff --git a/apps/challenge-user-service/.openapi-generator/FILES b/apps/challenge-user-service/.openapi-generator/FILES index ffa03dc705..823cad3893 100644 --- a/apps/challenge-user-service/.openapi-generator/FILES +++ b/apps/challenge-user-service/.openapi-generator/FILES @@ -5,8 +5,8 @@ src/main/java/org/sagebionetworks/challenge/api/UserApiController.java src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java -src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java -src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java -src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java +src/main/java/org/sagebionetworks/challenge/model/dto/User.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java src/main/resources/openapi.yaml src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index abb2d80d46..7b5370d504 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -17,7 +17,6 @@ "delegatePattern": true, "hideGenerationTimestamp": true, "library": "spring-boot", - "modelNameSuffix": "Dto", "modelPackage": "org.sagebionetworks.challenge.model.dto", "useTags": true } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java index 4629f8575f..f36d11b629 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java @@ -14,8 +14,8 @@ import javax.annotation.Generated; import javax.validation.Valid; import javax.validation.constraints.*; -import org.sagebionetworks.challenge.model.dto.UserDto; -import org.sagebionetworks.challenge.model.dto.UserUpdateRequestDto; +import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -33,7 +33,7 @@ default UserApiDelegate getDelegate() { /** * POST /api/v1/users/register * - * @param userDto (required) + * @param user (required) * @return OK (status code 200) */ @Operation( @@ -43,19 +43,16 @@ default UserApiDelegate getDelegate() { @ApiResponse( responseCode = "200", description = "OK", - content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) - }) + content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) }) @RequestMapping( method = RequestMethod.POST, value = "/api/v1/users/register", produces = {"*/*"}, consumes = {"application/json"}) - default ResponseEntity createUser( - @Parameter(name = "UserDto", description = "", required = true) @Valid @RequestBody - UserDto userDto) { - return getDelegate().createUser(userDto); + default ResponseEntity createUser( + @Parameter(name = "User", description = "", required = true) @Valid @RequestBody User user) { + return getDelegate().createUser(user); } /** @@ -71,15 +68,13 @@ default ResponseEntity createUser( @ApiResponse( responseCode = "200", description = "OK", - content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) - }) + content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) }) @RequestMapping( method = RequestMethod.GET, value = "/api/v1/users/{id}", produces = {"*/*"}) - default ResponseEntity getUser( + default ResponseEntity getUser( @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id) { return getDelegate().getUser(id); } @@ -100,15 +95,13 @@ default ResponseEntity getUser( @ApiResponse( responseCode = "200", description = "OK", - content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) - }) + content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) }) @RequestMapping( method = RequestMethod.GET, value = "/api/v1/users/", produces = {"*/*"}) - default ResponseEntity> listUsers( + default ResponseEntity> listUsers( @Min(0) @Parameter(name = "page", description = "Zero-based page index (0..N)") @Valid @@ -133,7 +126,7 @@ default ResponseEntity> listUsers( * PATCH /api/v1/users/{id} * * @param id (required) - * @param userUpdateRequestDto (required) + * @param userUpdateRequest (required) * @return OK (status code 200) */ @Operation( @@ -143,21 +136,17 @@ default ResponseEntity> listUsers( @ApiResponse( responseCode = "200", description = "OK", - content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) - }) + content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) }) @RequestMapping( method = RequestMethod.PATCH, value = "/api/v1/users/{id}", produces = {"*/*"}, consumes = {"application/json"}) - default ResponseEntity updateUser( + default ResponseEntity updateUser( @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id, - @Parameter(name = "UserUpdateRequestDto", description = "", required = true) - @Valid - @RequestBody - UserUpdateRequestDto userUpdateRequestDto) { - return getDelegate().updateUser(id, userUpdateRequestDto); + @Parameter(name = "UserUpdateRequest", description = "", required = true) @Valid @RequestBody + UserUpdateRequest userUpdateRequest) { + return getDelegate().updateUser(id, userUpdateRequest); } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java index 4af10580ac..cb2e0cc98f 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java @@ -3,8 +3,8 @@ import java.util.List; import java.util.Optional; import javax.annotation.Generated; -import org.sagebionetworks.challenge.model.dto.UserDto; -import org.sagebionetworks.challenge.model.dto.UserUpdateRequestDto; +import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -24,11 +24,11 @@ default Optional getRequest() { /** * POST /api/v1/users/register * - * @param userDto (required) + * @param user (required) * @return OK (status code 200) * @see UserApi#createUser */ - default ResponseEntity createUser(UserDto userDto) { + default ResponseEntity createUser(User user) { getRequest() .ifPresent( request -> { @@ -51,7 +51,7 @@ default ResponseEntity createUser(UserDto userDto) { * @return OK (status code 200) * @see UserApi#getUser */ - default ResponseEntity getUser(Long id) { + default ResponseEntity getUser(Long id) { getRequest() .ifPresent( request -> { @@ -77,7 +77,7 @@ default ResponseEntity getUser(Long id) { * @return OK (status code 200) * @see UserApi#listUsers */ - default ResponseEntity> listUsers(Integer page, Integer size, List sort) { + default ResponseEntity> listUsers(Integer page, Integer size, List sort) { getRequest() .ifPresent( request -> { @@ -97,11 +97,11 @@ default ResponseEntity> listUsers(Integer page, Integer size, List * PATCH /api/v1/users/{id} * * @param id (required) - * @param userUpdateRequestDto (required) + * @param userUpdateRequest (required) * @return OK (status code 200) * @see UserApi#updateUser */ - default ResponseEntity updateUser(Long id, UserUpdateRequestDto userUpdateRequestDto) { + default ResponseEntity updateUser(Long id, UserUpdateRequest userUpdateRequest) { getRequest() .ifPresent( request -> { diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index 963fee04d3..aa6ffc4732 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -1,6 +1,6 @@ package org.sagebionetworks.challenge.api; -import org.sagebionetworks.challenge.model.dto.UserDto; +import org.sagebionetworks.challenge.model.dto.User; import org.sagebionetworks.challenge.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -13,7 +13,7 @@ public class UserApiDelegateImpl implements UserApiDelegate { @Autowired UserService userService; @Override - public ResponseEntity createUser(UserDto userDto) { + public ResponseEntity createUser(User user) { // getRequest() // .ifPresent( // request -> { diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java similarity index 87% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java index 708aeb0c8f..a78a21b060 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java @@ -1,7 +1,6 @@ package org.sagebionetworks.challenge.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonTypeName; import io.swagger.v3.oas.annotations.media.Schema; import java.util.*; import java.util.Objects; @@ -9,13 +8,12 @@ import javax.validation.Valid; import javax.validation.constraints.*; -/** UserDto */ -@JsonTypeName("User") +/** User */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @lombok.AllArgsConstructor @lombok.Builder @lombok.NoArgsConstructor -public class UserDto { +public class User { @JsonProperty("id") private Long id; @@ -33,9 +31,9 @@ public class UserDto { private String authId; @JsonProperty("status") - private UserStatusDto status; + private UserStatus status; - public UserDto id(Long id) { + public User id(Long id) { this.id = id; return this; } @@ -54,7 +52,7 @@ public void setId(Long id) { this.id = id; } - public UserDto username(String username) { + public User username(String username) { this.username = username; return this; } @@ -73,7 +71,7 @@ public void setUsername(String username) { this.username = username; } - public UserDto email(String email) { + public User email(String email) { this.email = email; return this; } @@ -92,7 +90,7 @@ public void setEmail(String email) { this.email = email; } - public UserDto password(String password) { + public User password(String password) { this.password = password; return this; } @@ -111,7 +109,7 @@ public void setPassword(String password) { this.password = password; } - public UserDto authId(String authId) { + public User authId(String authId) { this.authId = authId; return this; } @@ -130,7 +128,7 @@ public void setAuthId(String authId) { this.authId = authId; } - public UserDto status(UserStatusDto status) { + public User status(UserStatus status) { this.status = status; return this; } @@ -142,11 +140,11 @@ public UserDto status(UserStatusDto status) { */ @Valid @Schema(name = "status", required = false) - public UserStatusDto getStatus() { + public UserStatus getStatus() { return status; } - public void setStatus(UserStatusDto status) { + public void setStatus(UserStatus status) { this.status = status; } @@ -158,7 +156,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - UserDto user = (UserDto) o; + User user = (User) o; return Objects.equals(this.id, user.id) && Objects.equals(this.username, user.username) && Objects.equals(this.email, user.email) @@ -175,7 +173,7 @@ public int hashCode() { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("class UserDto {\n"); + sb.append("class User {\n"); sb.append(" id: ").append(toIndentedString(id)).append("\n"); sb.append(" username: ").append(toIndentedString(username)).append("\n"); sb.append(" email: ").append(toIndentedString(email)).append("\n"); diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java similarity index 82% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java index c0fc7fe505..0d1c5af11b 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java @@ -8,7 +8,7 @@ /** Gets or Sets UserStatus */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public enum UserStatusDto { +public enum UserStatus { PENDING("PENDING"), APPROVED("APPROVED"), @@ -19,7 +19,7 @@ public enum UserStatusDto { private String value; - UserStatusDto(String value) { + UserStatus(String value) { this.value = value; } @@ -34,8 +34,8 @@ public String toString() { } @JsonCreator - public static UserStatusDto fromValue(String value) { - for (UserStatusDto b : UserStatusDto.values()) { + public static UserStatus fromValue(String value) { + for (UserStatus b : UserStatus.values()) { if (b.value.equals(value)) { return b; } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java similarity index 76% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java index 83e512ccb7..0f8ddcc815 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java @@ -1,7 +1,6 @@ package org.sagebionetworks.challenge.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonTypeName; import io.swagger.v3.oas.annotations.media.Schema; import java.util.*; import java.util.Objects; @@ -9,18 +8,17 @@ import javax.validation.Valid; import javax.validation.constraints.*; -/** UserUpdateRequestDto */ -@JsonTypeName("UserUpdateRequest") +/** UserUpdateRequest */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @lombok.AllArgsConstructor @lombok.Builder @lombok.NoArgsConstructor -public class UserUpdateRequestDto { +public class UserUpdateRequest { @JsonProperty("status") - private UserStatusDto status; + private UserStatus status; - public UserUpdateRequestDto status(UserStatusDto status) { + public UserUpdateRequest status(UserStatus status) { this.status = status; return this; } @@ -32,11 +30,11 @@ public UserUpdateRequestDto status(UserStatusDto status) { */ @Valid @Schema(name = "status", required = false) - public UserStatusDto getStatus() { + public UserStatus getStatus() { return status; } - public void setStatus(UserStatusDto status) { + public void setStatus(UserStatus status) { this.status = status; } @@ -48,7 +46,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - UserUpdateRequestDto userUpdateRequest = (UserUpdateRequestDto) o; + UserUpdateRequest userUpdateRequest = (UserUpdateRequest) o; return Objects.equals(this.status, userUpdateRequest.status); } @@ -60,7 +58,7 @@ public int hashCode() { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("class UserUpdateRequestDto {\n"); + sb.append("class UserUpdateRequest {\n"); sb.append(" status: ").append(toIndentedString(status)).append("\n"); sb.append("}"); return sb.toString(); diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java index 00b30d65c4..d2c08a3fb1 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java @@ -10,7 +10,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import org.sagebionetworks.challenge.model.dto.UserStatusDto; +import org.sagebionetworks.challenge.model.dto.UserStatus; @Getter @Setter @@ -26,9 +26,9 @@ public class UserEntity { private String authId; @Enumerated(EnumType.STRING) - private UserStatusDto status; + private UserStatus status; - public UserEntity(String username, String authId, UserStatusDto status) { + public UserEntity(String username, String authId, UserStatus status) { this.username = username; this.authId = authId; this.status = status; diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java index 2b8bb930c8..bd125d942e 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java @@ -1,13 +1,13 @@ package org.sagebionetworks.challenge.model.mapper; -import org.sagebionetworks.challenge.model.dto.UserDto; +import org.sagebionetworks.challenge.model.dto.User; import org.sagebionetworks.challenge.model.entity.UserEntity; import org.sagebionetworks.challenge.util.model.mapper.BaseMapper; import org.springframework.beans.BeanUtils; -public class UserMapper extends BaseMapper { +public class UserMapper extends BaseMapper { @Override - public UserEntity convertToEntity(UserDto dto, Object... args) { + public UserEntity convertToEntity(User dto, Object... args) { UserEntity userEntity = new UserEntity(); if (dto != null) { BeanUtils.copyProperties(dto, userEntity); @@ -16,8 +16,8 @@ public UserEntity convertToEntity(UserDto dto, Object... args) { } @Override - public UserDto convertToDto(UserEntity entity, Object... args) { - UserDto user = new UserDto(); + public User convertToDto(UserEntity entity, Object... args) { + User user = new User(); if (entity != null) { BeanUtils.copyProperties(entity, user); } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java index c5177781ae..1c4a364927 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java @@ -10,9 +10,9 @@ import org.sagebionetworks.challenge.exception.GlobalErrorCode; import org.sagebionetworks.challenge.exception.InvalidUserException; import org.sagebionetworks.challenge.exception.UserAlreadyRegisteredException; -import org.sagebionetworks.challenge.model.dto.UserDto; -import org.sagebionetworks.challenge.model.dto.UserStatusDto; -import org.sagebionetworks.challenge.model.dto.UserUpdateRequestDto; +import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.dto.UserStatus; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; import org.sagebionetworks.challenge.model.entity.UserEntity; import org.sagebionetworks.challenge.model.mapper.UserMapper; import org.sagebionetworks.challenge.model.repository.UserRepository; @@ -32,7 +32,7 @@ public class UserService { private UserMapper userMapper = new UserMapper(); - public UserDto createUser(UserDto user) { + public User createUser(User user) { if (keycloakUserService.getUserByUsername(user.getUsername()).isPresent()) { throw new UserAlreadyRegisteredException( "This username is already registered.", GlobalErrorCode.ERROR_USERNAME_REGISTERED); @@ -55,7 +55,7 @@ public UserDto createUser(UserDto user) { Optional representation = keycloakUserService.getUserByUsername(user.getUsername()); user.setAuthId(representation.get().getId()); - user.setStatus(UserStatusDto.PENDING); + user.setStatus(UserStatus.PENDING); UserEntity userEntity = userRepository.save(userMapper.convertToEntity(user)); return userMapper.convertToDto(userEntity); } @@ -64,9 +64,9 @@ public UserDto createUser(UserDto user) { "Unable to create the new user", GlobalErrorCode.ERROR_INVALID_USER); } - public List listUsers(Pageable pageable) { + public List listUsers(Pageable pageable) { Page allUsersInDb = userRepository.findAll(pageable); - List users = userMapper.convertToDtoList(allUsersInDb.getContent()); + List users = userMapper.convertToDtoList(allUsersInDb.getContent()); users.forEach( user -> { UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); @@ -76,15 +76,15 @@ public List listUsers(Pageable pageable) { return users; } - public UserDto getUser(Long userId) { + public User getUser(Long userId) { return userMapper.convertToDto( userRepository.findById(userId).orElseThrow(EntityNotFoundException::new)); } - public UserDto updateUser(Long id, UserUpdateRequestDto userUpdateRequest) { + public User updateUser(Long id, UserUpdateRequest userUpdateRequest) { UserEntity userEntity = userRepository.findById(id).orElseThrow(EntityNotFoundException::new); - if (userUpdateRequest.getStatus() == UserStatusDto.APPROVED) { + if (userUpdateRequest.getStatus() == UserStatus.APPROVED) { UserRepresentation userRepresentation = keycloakUserService.getUser(userEntity.getAuthId()); userRepresentation.setEnabled(true); userRepresentation.setEmailVerified(true); diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index 74a4e8dae0..b42e0ac622 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -172,6 +172,8 @@ components: - '@lombok.Builder' - '@lombok.NoArgsConstructor' UserUpdateRequest: + example: + status: PENDING properties: status: $ref: '#/components/schemas/UserStatus' From a83db98055ca47e1afea8b7cf17f003dfc58f3a9 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Thu, 22 Sep 2022 18:18:50 +0000 Subject: [PATCH 42/62] Minor update --- .../challenge/api/UserApiDelegateImpl.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index aa6ffc4732..db578033e1 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -30,4 +30,12 @@ public ResponseEntity createUser(User user) { // }); return new ResponseEntity<>(HttpStatus.ACCEPTED); } + + // @Override + // public ResponseEntity> listUsers(Integer page, Integer size, List sort) { + // log.info("List all the users"); + + // Pageable pageable = PageRequest.of(0, 2, sort); + // return ResponseEntity.ok(userService.listUsers(pageable)); + // } } From afff64d04ae8107b4a0cc31b4d91985e2b992496 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 23 Sep 2022 00:04:06 +0000 Subject: [PATCH 43/62] Find a solution to Pageable --- .../.openapi-generator/FILES | 1 + apps/challenge-user-service/openapi.yaml | 46 +++--- apps/challenge-user-service/openapitools.json | 5 +- .../challenge/api/UserApi.java | 26 +--- .../challenge/api/UserApiDelegate.java | 8 +- .../challenge/api/UserApiDelegateImpl.java | 13 +- .../challenge/model/dto/Pageable.java | 140 ++++++++++++++++++ .../src/main/resources/openapi.yaml | 50 +++---- 8 files changed, 210 insertions(+), 79 deletions(-) create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/Pageable.java diff --git a/apps/challenge-user-service/.openapi-generator/FILES b/apps/challenge-user-service/.openapi-generator/FILES index 823cad3893..1f80a9c2a6 100644 --- a/apps/challenge-user-service/.openapi-generator/FILES +++ b/apps/challenge-user-service/.openapi-generator/FILES @@ -5,6 +5,7 @@ src/main/java/org/sagebionetworks/challenge/api/UserApiController.java src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java +src/main/java/org/sagebionetworks/challenge/model/dto/Pageable.java src/main/java/org/sagebionetworks/challenge/model/dto/User.java src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java diff --git a/apps/challenge-user-service/openapi.yaml b/apps/challenge-user-service/openapi.yaml index 4384fb7f46..7151329214 100644 --- a/apps/challenge-user-service/openapi.yaml +++ b/apps/challenge-user-service/openapi.yaml @@ -84,31 +84,11 @@ paths: - User operationId: listUsers parameters: - - name: page + - name: pageable in: query - description: Zero-based page index (0..N) required: false schema: - minimum: 0 - type: integer - default: 0 - - name: size - in: query - description: The size of the page to be returned - required: false - schema: - minimum: 1 - type: integer - default: 20 - - name: sort - in: query - description: "Sorting criteria in the format: property,(asc|desc). Default\ - \ sort order is ascending. Multiple sort criteria are supported." - required: false - schema: - type: array - items: - type: string + $ref: '#/components/schemas/Pageable' responses: "200": description: OK @@ -156,4 +136,24 @@ components: - APPROVED - DISABLED - BLACKLIST - example: PENDING \ No newline at end of file + example: PENDING + Pageable: + type: object + properties: + page: + description: Zero-based page index (0..N) + type: integer + default: 0 + minimum: 0 + size: + description: The size of the page to be returned + type: integer + default: 20 + minimum: 1 + sort: + description: "Sorting criteria in the format: property,(asc|desc). Default\ + \ sort order is ascending. Multiple sort criteria are supported." + type: array + items: + type: string + example: id,asc \ No newline at end of file diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index 7b5370d504..0c150843a8 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -18,7 +18,10 @@ "hideGenerationTimestamp": true, "library": "spring-boot", "modelPackage": "org.sagebionetworks.challenge.model.dto", - "useTags": true + "useTags": true, + "importMappings": { + "Pageable": "org.springframework.data.domain.Pageable" + } } } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java index f36d11b629..3201a94a80 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java @@ -16,6 +16,7 @@ import javax.validation.constraints.*; import org.sagebionetworks.challenge.model.dto.User; import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; +import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -82,10 +83,7 @@ default ResponseEntity getUser( /** * GET /api/v1/users/ * - * @param page Zero-based page index (0..N) (optional, default to 0) - * @param size The size of the page to be returned (optional, default to 20) - * @param sort Sorting criteria in the format: property,(asc|desc). Default sort order is - * ascending. Multiple sort criteria are supported. (optional) + * @param pageable (optional) * @return OK (status code 200) */ @Operation( @@ -102,24 +100,8 @@ default ResponseEntity getUser( value = "/api/v1/users/", produces = {"*/*"}) default ResponseEntity> listUsers( - @Min(0) - @Parameter(name = "page", description = "Zero-based page index (0..N)") - @Valid - @RequestParam(value = "page", required = false, defaultValue = "0") - Integer page, - @Min(1) - @Parameter(name = "size", description = "The size of the page to be returned") - @Valid - @RequestParam(value = "size", required = false, defaultValue = "20") - Integer size, - @Parameter( - name = "sort", - description = - "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.") - @Valid - @RequestParam(value = "sort", required = false) - List sort) { - return getDelegate().listUsers(page, size, sort); + @Parameter(name = "pageable", description = "") @Valid Pageable pageable) { + return getDelegate().listUsers(pageable); } /** diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java index cb2e0cc98f..d5d6fd7040 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java @@ -5,6 +5,7 @@ import javax.annotation.Generated; import org.sagebionetworks.challenge.model.dto.User; import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -70,14 +71,11 @@ default ResponseEntity getUser(Long id) { /** * GET /api/v1/users/ * - * @param page Zero-based page index (0..N) (optional, default to 0) - * @param size The size of the page to be returned (optional, default to 20) - * @param sort Sorting criteria in the format: property,(asc|desc). Default sort order is - * ascending. Multiple sort criteria are supported. (optional) + * @param pageable (optional) * @return OK (status code 200) * @see UserApi#listUsers */ - default ResponseEntity> listUsers(Integer page, Integer size, List sort) { + default ResponseEntity> listUsers(Pageable pageable) { getRequest() .ifPresent( request -> { diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index db578033e1..6776caa657 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -1,12 +1,16 @@ package org.sagebionetworks.challenge.api; +import java.util.List; +import lombok.extern.slf4j.Slf4j; import org.sagebionetworks.challenge.model.dto.User; import org.sagebionetworks.challenge.service.UserService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; +@Slf4j @Component public class UserApiDelegateImpl implements UserApiDelegate { @@ -31,7 +35,14 @@ public ResponseEntity createUser(User user) { return new ResponseEntity<>(HttpStatus.ACCEPTED); } - // @Override + @Override + public ResponseEntity> listUsers(Pageable pageable) { + log.info("List all the users"); + log.info(pageable.toString()); + return new ResponseEntity<>(HttpStatus.ACCEPTED); + // return ResponseEntity.ok(userService.listUsers(pageable)); + } + // public ResponseEntity> listUsers(Integer page, Integer size, List sort) { // log.info("List all the users"); diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/Pageable.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/Pageable.java new file mode 100644 index 0000000000..67145b6ed0 --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/Pageable.java @@ -0,0 +1,140 @@ +package org.sagebionetworks.challenge.model.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import javax.annotation.Generated; +import javax.validation.Valid; +import javax.validation.constraints.*; + +/** Pageable */ +@Generated(value = "org.openapitools.codegen.languages.SpringCodegen") +// TODO Add x-java-class-annotations +public class Pageable { + + @JsonProperty("page") + private Integer page = 0; + + @JsonProperty("size") + private Integer size = 20; + + @JsonProperty("sort") + @Valid + private List sort = null; + + public Pageable page(Integer page) { + this.page = page; + return this; + } + + /** + * Zero-based page index (0..N) minimum: 0 + * + * @return page + */ + @Min(0) + @Schema(name = "page", description = "Zero-based page index (0..N)", required = false) + public Integer getPage() { + return page; + } + + public void setPage(Integer page) { + this.page = page; + } + + public Pageable size(Integer size) { + this.size = size; + return this; + } + + /** + * The size of the page to be returned minimum: 1 + * + * @return size + */ + @Min(1) + @Schema(name = "size", description = "The size of the page to be returned", required = false) + public Integer getSize() { + return size; + } + + public void setSize(Integer size) { + this.size = size; + } + + public Pageable sort(List sort) { + this.sort = sort; + return this; + } + + public Pageable addSortItem(String sortItem) { + if (this.sort == null) { + this.sort = new ArrayList<>(); + } + this.sort.add(sortItem); + return this; + } + + /** + * Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple + * sort criteria are supported. + * + * @return sort + */ + @Schema( + name = "sort", + example = "id,asc", + description = + "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + required = false) + public List getSort() { + return sort; + } + + public void setSort(List sort) { + this.sort = sort; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Pageable pageable = (Pageable) o; + return Objects.equals(this.page, pageable.page) + && Objects.equals(this.size, pageable.size) + && Objects.equals(this.sort, pageable.sort); + } + + @Override + public int hashCode() { + return Objects.hash(page, size, sort); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Pageable {\n"); + sb.append(" page: ").append(toIndentedString(page)).append("\n"); + sb.append(" size: ").append(toIndentedString(size)).append("\n"); + sb.append(" sort: ").append(toIndentedString(sort)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index b42e0ac622..ca523751ae 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -97,36 +97,12 @@ paths: get: operationId: listUsers parameters: - - description: Zero-based page index (0..N) - explode: true + - explode: true in: query - name: page + name: pageable required: false schema: - default: 0 - minimum: 0 - type: integer - style: form - - description: The size of the page to be returned - explode: true - in: query - name: size - required: false - schema: - default: 20 - minimum: 1 - type: integer - style: form - - description: "Sorting criteria in the format: property,(asc|desc). Default\ - \ sort order is ascending. Multiple sort criteria are supported." - explode: true - in: query - name: sort - required: false - schema: - items: - type: string - type: array + $ref: '#/components/schemas/Pageable' style: form responses: "200": @@ -190,3 +166,23 @@ components: - BLACKLIST example: PENDING type: string + Pageable: + properties: + page: + default: 0 + description: Zero-based page index (0..N) + minimum: 0 + type: integer + size: + default: 20 + description: The size of the page to be returned + minimum: 1 + type: integer + sort: + description: "Sorting criteria in the format: property,(asc|desc). Default\ + \ sort order is ascending. Multiple sort criteria are supported." + example: "id,asc" + items: + type: string + type: array + type: object From fabcf11b39f8359dd32f54b9df130bdb90e6c470 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 23 Sep 2022 15:50:08 +0000 Subject: [PATCH 44/62] Specify app class in build.gradle --- apps/challenge-user-service/build.gradle | 8 ++++++-- .../challenge/api/UserApiDelegateImpl.java | 11 ++--------- .../challenge/service/UserService.java | 19 ++++++++++--------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index 140a18084b..80e26d561c 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -35,13 +35,13 @@ dependencies { implementation "org.keycloak:keycloak-spring-boot-starter:${keycloakVersion}" implementation "org.sagebionetworks.challenge:challenge-util:${challengeVersion}" implementation "org.springframework.boot:spring-boot-devtools:${springBootVersion}" + implementation "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-validation:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" implementation "org.springframework.data:spring-data-commons:${springDataVersion}" runtimeOnly 'mysql:mysql-connector-java:8.0.30' testImplementation "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" - } group = 'org.sagebionetworks.challenge' @@ -54,7 +54,11 @@ java { } tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' + options.encoding = 'UTF-8' +} + +springBoot { + mainClass = 'org.sagebionetworks.challenge.ChallengeUserServiceApplication' } spotless { diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index 6776caa657..2a92c36a3b 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -39,14 +39,7 @@ public ResponseEntity createUser(User user) { public ResponseEntity> listUsers(Pageable pageable) { log.info("List all the users"); log.info(pageable.toString()); - return new ResponseEntity<>(HttpStatus.ACCEPTED); - // return ResponseEntity.ok(userService.listUsers(pageable)); + // return new ResponseEntity<>(HttpStatus.ACCEPTED); + return ResponseEntity.ok(userService.listUsers(pageable)); } - - // public ResponseEntity> listUsers(Integer page, Integer size, List sort) { - // log.info("List all the users"); - - // Pageable pageable = PageRequest.of(0, 2, sort); - // return ResponseEntity.ok(userService.listUsers(pageable)); - // } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java index 1c4a364927..039798c677 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java @@ -1,5 +1,6 @@ package org.sagebionetworks.challenge.service; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -17,7 +18,6 @@ import org.sagebionetworks.challenge.model.mapper.UserMapper; import org.sagebionetworks.challenge.model.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -65,14 +65,15 @@ public User createUser(User user) { } public List listUsers(Pageable pageable) { - Page allUsersInDb = userRepository.findAll(pageable); - List users = userMapper.convertToDtoList(allUsersInDb.getContent()); - users.forEach( - user -> { - UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); - user.setId(user.getId()); - user.setEmail(userRepresentation.getEmail()); - }); + // Page allUsersInDb = userRepository.findAll(pageable); + List users = new ArrayList<>(); + // List users = userMapper.convertToDtoList(allUsersInDb.getContent()); + // users.forEach( + // user -> { + // UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); + // user.setId(user.getId()); + // user.setEmail(userRepresentation.getEmail()); + // }); return users; } From c4ac5a2629522ffd1154ad5782a6fcb7db9e12ab Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 23 Sep 2022 15:54:08 +0000 Subject: [PATCH 45/62] Move spec to folder `api-spec` --- apps/challenge-user-service/{ => api-spec}/openapi.yaml | 0 apps/challenge-user-service/openapitools.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename apps/challenge-user-service/{ => api-spec}/openapi.yaml (100%) diff --git a/apps/challenge-user-service/openapi.yaml b/apps/challenge-user-service/api-spec/openapi.yaml similarity index 100% rename from apps/challenge-user-service/openapi.yaml rename to apps/challenge-user-service/api-spec/openapi.yaml diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index 0c150843a8..15211df1a9 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -7,7 +7,7 @@ "challenge-user-service": { "config": "templates/config.yaml", "generatorName": "spring", - "inputSpec": "openapi.yaml", + "inputSpec": "api-spec/openapi.yaml", "output": "#{cwd}", "templateDir": "templates", "additionalProperties": { From b07dab083d61e624551c8c958917e8a531945f24 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 23 Sep 2022 17:56:47 +0000 Subject: [PATCH 46/62] Update UserEntity --- .../challenge/model/entity/UserEntity.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java index d2c08a3fb1..ac30be248e 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java @@ -1,5 +1,6 @@ package org.sagebionetworks.challenge.model.entity; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; @@ -7,30 +8,37 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; -import lombok.Getter; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Setter; import org.sagebionetworks.challenge.model.dto.UserStatus; -@Getter -@Setter +/** + * The User information saved to DB. + * + *

The following properties are saved in Keycloak: email, password (hash). + */ @Entity @Table(name = "challenge_user") +@Data +@Builder @NoArgsConstructor +@AllArgsConstructor public class UserEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false, updatable = false) private Long id; + @Column(nullable = false) private String username; + + @Column(nullable = false) private String authId; @Enumerated(EnumType.STRING) + @Column(nullable = false) private UserStatus status; - - public UserEntity(String username, String authId, UserStatus status) { - this.username = username; - this.authId = authId; - this.status = status; - } } From b7bf7e6ce99c86bf343d0503bf28e9874c8349ad Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 23 Sep 2022 18:11:07 +0000 Subject: [PATCH 47/62] Add Dto suffix to model --- .../.openapi-generator/FILES | 8 +-- apps/challenge-user-service/openapitools.json | 1 + .../challenge/api/UserApi.java | 49 ++++++++++++------- .../challenge/api/UserApiDelegate.java | 18 +++---- .../challenge/api/UserApiDelegateImpl.java | 20 ++++---- .../dto/{Pageable.java => PageableDto.java} | 18 ++++--- .../model/dto/{User.java => UserDto.java} | 28 ++++++----- .../{UserStatus.java => UserStatusDto.java} | 8 +-- ...Request.java => UserUpdateRequestDto.java} | 18 ++++--- .../challenge/model/entity/UserEntity.java | 4 +- .../challenge/model/mapper/UserMapper.java | 10 ++-- .../challenge/service/UserService.java | 20 ++++---- .../src/main/resources/openapi.yaml | 2 - 13 files changed, 109 insertions(+), 95 deletions(-) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/{Pageable.java => PageableDto.java} (88%) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/{User.java => UserDto.java} (87%) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/{UserStatus.java => UserStatusDto.java} (82%) rename apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/{UserUpdateRequest.java => UserUpdateRequestDto.java} (76%) diff --git a/apps/challenge-user-service/.openapi-generator/FILES b/apps/challenge-user-service/.openapi-generator/FILES index 1f80a9c2a6..5812d82cdc 100644 --- a/apps/challenge-user-service/.openapi-generator/FILES +++ b/apps/challenge-user-service/.openapi-generator/FILES @@ -5,9 +5,9 @@ src/main/java/org/sagebionetworks/challenge/api/UserApiController.java src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java src/main/java/org/sagebionetworks/challenge/configuration/HomeController.java src/main/java/org/sagebionetworks/challenge/configuration/SpringDocConfiguration.java -src/main/java/org/sagebionetworks/challenge/model/dto/Pageable.java -src/main/java/org/sagebionetworks/challenge/model/dto/User.java -src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java -src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +src/main/java/org/sagebionetworks/challenge/model/dto/PageableDto.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java +src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java src/main/resources/openapi.yaml src/test/java/org/sagebionetworks/challenge/OpenApiGeneratorApplicationTests.java diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index 15211df1a9..dd37e0e6cf 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -19,6 +19,7 @@ "library": "spring-boot", "modelPackage": "org.sagebionetworks.challenge.model.dto", "useTags": true, + "modelNameSuffix": "Dto", "importMappings": { "Pageable": "org.springframework.data.domain.Pageable" } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java index 3201a94a80..b7c87629a7 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java @@ -14,9 +14,9 @@ import javax.annotation.Generated; import javax.validation.Valid; import javax.validation.constraints.*; -import org.sagebionetworks.challenge.model.dto.User; -import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; -import org.springframework.data.domain.Pageable; +import org.sagebionetworks.challenge.model.dto.PageableDto; +import org.sagebionetworks.challenge.model.dto.UserDto; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequestDto; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -34,7 +34,7 @@ default UserApiDelegate getDelegate() { /** * POST /api/v1/users/register * - * @param user (required) + * @param userDto (required) * @return OK (status code 200) */ @Operation( @@ -44,16 +44,19 @@ default UserApiDelegate getDelegate() { @ApiResponse( responseCode = "200", description = "OK", - content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + }) }) @RequestMapping( method = RequestMethod.POST, value = "/api/v1/users/register", produces = {"*/*"}, consumes = {"application/json"}) - default ResponseEntity createUser( - @Parameter(name = "User", description = "", required = true) @Valid @RequestBody User user) { - return getDelegate().createUser(user); + default ResponseEntity createUser( + @Parameter(name = "UserDto", description = "", required = true) @Valid @RequestBody + UserDto userDto) { + return getDelegate().createUser(userDto); } /** @@ -69,13 +72,15 @@ default ResponseEntity createUser( @ApiResponse( responseCode = "200", description = "OK", - content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + }) }) @RequestMapping( method = RequestMethod.GET, value = "/api/v1/users/{id}", produces = {"*/*"}) - default ResponseEntity getUser( + default ResponseEntity getUser( @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id) { return getDelegate().getUser(id); } @@ -93,14 +98,16 @@ default ResponseEntity getUser( @ApiResponse( responseCode = "200", description = "OK", - content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + }) }) @RequestMapping( method = RequestMethod.GET, value = "/api/v1/users/", produces = {"*/*"}) - default ResponseEntity> listUsers( - @Parameter(name = "pageable", description = "") @Valid Pageable pageable) { + default ResponseEntity> listUsers( + @Parameter(name = "pageable", description = "") @Valid PageableDto pageable) { return getDelegate().listUsers(pageable); } @@ -108,7 +115,7 @@ default ResponseEntity> listUsers( * PATCH /api/v1/users/{id} * * @param id (required) - * @param userUpdateRequest (required) + * @param userUpdateRequestDto (required) * @return OK (status code 200) */ @Operation( @@ -118,17 +125,21 @@ default ResponseEntity> listUsers( @ApiResponse( responseCode = "200", description = "OK", - content = {@Content(mediaType = "*/*", schema = @Schema(implementation = User.class))}) + content = { + @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + }) }) @RequestMapping( method = RequestMethod.PATCH, value = "/api/v1/users/{id}", produces = {"*/*"}, consumes = {"application/json"}) - default ResponseEntity updateUser( + default ResponseEntity updateUser( @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id, - @Parameter(name = "UserUpdateRequest", description = "", required = true) @Valid @RequestBody - UserUpdateRequest userUpdateRequest) { - return getDelegate().updateUser(id, userUpdateRequest); + @Parameter(name = "UserUpdateRequestDto", description = "", required = true) + @Valid + @RequestBody + UserUpdateRequestDto userUpdateRequestDto) { + return getDelegate().updateUser(id, userUpdateRequestDto); } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java index d5d6fd7040..38ce919d16 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java @@ -3,9 +3,9 @@ import java.util.List; import java.util.Optional; import javax.annotation.Generated; -import org.sagebionetworks.challenge.model.dto.User; -import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; -import org.springframework.data.domain.Pageable; +import org.sagebionetworks.challenge.model.dto.PageableDto; +import org.sagebionetworks.challenge.model.dto.UserDto; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequestDto; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -25,11 +25,11 @@ default Optional getRequest() { /** * POST /api/v1/users/register * - * @param user (required) + * @param userDto (required) * @return OK (status code 200) * @see UserApi#createUser */ - default ResponseEntity createUser(User user) { + default ResponseEntity createUser(UserDto userDto) { getRequest() .ifPresent( request -> { @@ -52,7 +52,7 @@ default ResponseEntity createUser(User user) { * @return OK (status code 200) * @see UserApi#getUser */ - default ResponseEntity getUser(Long id) { + default ResponseEntity getUser(Long id) { getRequest() .ifPresent( request -> { @@ -75,7 +75,7 @@ default ResponseEntity getUser(Long id) { * @return OK (status code 200) * @see UserApi#listUsers */ - default ResponseEntity> listUsers(Pageable pageable) { + default ResponseEntity> listUsers(PageableDto pageable) { getRequest() .ifPresent( request -> { @@ -95,11 +95,11 @@ default ResponseEntity> listUsers(Pageable pageable) { * PATCH /api/v1/users/{id} * * @param id (required) - * @param userUpdateRequest (required) + * @param userUpdateRequestDto (required) * @return OK (status code 200) * @see UserApi#updateUser */ - default ResponseEntity updateUser(Long id, UserUpdateRequest userUpdateRequest) { + default ResponseEntity updateUser(Long id, UserUpdateRequestDto userUpdateRequestDto) { getRequest() .ifPresent( request -> { diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index 2a92c36a3b..f1bc39f4bd 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -1,11 +1,9 @@ package org.sagebionetworks.challenge.api; -import java.util.List; import lombok.extern.slf4j.Slf4j; -import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.dto.UserDto; import org.sagebionetworks.challenge.service.UserService; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -17,7 +15,7 @@ public class UserApiDelegateImpl implements UserApiDelegate { @Autowired UserService userService; @Override - public ResponseEntity createUser(User user) { + public ResponseEntity createUser(UserDto user) { // getRequest() // .ifPresent( // request -> { @@ -35,11 +33,11 @@ public ResponseEntity createUser(User user) { return new ResponseEntity<>(HttpStatus.ACCEPTED); } - @Override - public ResponseEntity> listUsers(Pageable pageable) { - log.info("List all the users"); - log.info(pageable.toString()); - // return new ResponseEntity<>(HttpStatus.ACCEPTED); - return ResponseEntity.ok(userService.listUsers(pageable)); - } + // @Override + // public ResponseEntity> listUsers(Pageable pageable) { + // log.info("List all the users"); + // log.info(pageable.toString()); + // // return new ResponseEntity<>(HttpStatus.ACCEPTED); + // return ResponseEntity.ok(userService.listUsers(pageable)); + // } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/Pageable.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/PageableDto.java similarity index 88% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/Pageable.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/PageableDto.java index 67145b6ed0..f635b895b5 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/Pageable.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/PageableDto.java @@ -1,6 +1,7 @@ package org.sagebionetworks.challenge.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; import io.swagger.v3.oas.annotations.media.Schema; import java.util.*; import java.util.ArrayList; @@ -10,10 +11,11 @@ import javax.validation.Valid; import javax.validation.constraints.*; -/** Pageable */ +/** PageableDto */ +@JsonTypeName("Pageable") @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") // TODO Add x-java-class-annotations -public class Pageable { +public class PageableDto { @JsonProperty("page") private Integer page = 0; @@ -25,7 +27,7 @@ public class Pageable { @Valid private List sort = null; - public Pageable page(Integer page) { + public PageableDto page(Integer page) { this.page = page; return this; } @@ -45,7 +47,7 @@ public void setPage(Integer page) { this.page = page; } - public Pageable size(Integer size) { + public PageableDto size(Integer size) { this.size = size; return this; } @@ -65,12 +67,12 @@ public void setSize(Integer size) { this.size = size; } - public Pageable sort(List sort) { + public PageableDto sort(List sort) { this.sort = sort; return this; } - public Pageable addSortItem(String sortItem) { + public PageableDto addSortItem(String sortItem) { if (this.sort == null) { this.sort = new ArrayList<>(); } @@ -106,7 +108,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - Pageable pageable = (Pageable) o; + PageableDto pageable = (PageableDto) o; return Objects.equals(this.page, pageable.page) && Objects.equals(this.size, pageable.size) && Objects.equals(this.sort, pageable.sort); @@ -120,7 +122,7 @@ public int hashCode() { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("class Pageable {\n"); + sb.append("class PageableDto {\n"); sb.append(" page: ").append(toIndentedString(page)).append("\n"); sb.append(" size: ").append(toIndentedString(size)).append("\n"); sb.append(" sort: ").append(toIndentedString(sort)).append("\n"); diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java similarity index 87% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java index a78a21b060..708aeb0c8f 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/User.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java @@ -1,6 +1,7 @@ package org.sagebionetworks.challenge.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; import io.swagger.v3.oas.annotations.media.Schema; import java.util.*; import java.util.Objects; @@ -8,12 +9,13 @@ import javax.validation.Valid; import javax.validation.constraints.*; -/** User */ +/** UserDto */ +@JsonTypeName("User") @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @lombok.AllArgsConstructor @lombok.Builder @lombok.NoArgsConstructor -public class User { +public class UserDto { @JsonProperty("id") private Long id; @@ -31,9 +33,9 @@ public class User { private String authId; @JsonProperty("status") - private UserStatus status; + private UserStatusDto status; - public User id(Long id) { + public UserDto id(Long id) { this.id = id; return this; } @@ -52,7 +54,7 @@ public void setId(Long id) { this.id = id; } - public User username(String username) { + public UserDto username(String username) { this.username = username; return this; } @@ -71,7 +73,7 @@ public void setUsername(String username) { this.username = username; } - public User email(String email) { + public UserDto email(String email) { this.email = email; return this; } @@ -90,7 +92,7 @@ public void setEmail(String email) { this.email = email; } - public User password(String password) { + public UserDto password(String password) { this.password = password; return this; } @@ -109,7 +111,7 @@ public void setPassword(String password) { this.password = password; } - public User authId(String authId) { + public UserDto authId(String authId) { this.authId = authId; return this; } @@ -128,7 +130,7 @@ public void setAuthId(String authId) { this.authId = authId; } - public User status(UserStatus status) { + public UserDto status(UserStatusDto status) { this.status = status; return this; } @@ -140,11 +142,11 @@ public User status(UserStatus status) { */ @Valid @Schema(name = "status", required = false) - public UserStatus getStatus() { + public UserStatusDto getStatus() { return status; } - public void setStatus(UserStatus status) { + public void setStatus(UserStatusDto status) { this.status = status; } @@ -156,7 +158,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - User user = (User) o; + UserDto user = (UserDto) o; return Objects.equals(this.id, user.id) && Objects.equals(this.username, user.username) && Objects.equals(this.email, user.email) @@ -173,7 +175,7 @@ public int hashCode() { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("class User {\n"); + sb.append("class UserDto {\n"); sb.append(" id: ").append(toIndentedString(id)).append("\n"); sb.append(" username: ").append(toIndentedString(username)).append("\n"); sb.append(" email: ").append(toIndentedString(email)).append("\n"); diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java similarity index 82% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java index 0d1c5af11b..c0fc7fe505 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatus.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java @@ -8,7 +8,7 @@ /** Gets or Sets UserStatus */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public enum UserStatus { +public enum UserStatusDto { PENDING("PENDING"), APPROVED("APPROVED"), @@ -19,7 +19,7 @@ public enum UserStatus { private String value; - UserStatus(String value) { + UserStatusDto(String value) { this.value = value; } @@ -34,8 +34,8 @@ public String toString() { } @JsonCreator - public static UserStatus fromValue(String value) { - for (UserStatus b : UserStatus.values()) { + public static UserStatusDto fromValue(String value) { + for (UserStatusDto b : UserStatusDto.values()) { if (b.value.equals(value)) { return b; } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java similarity index 76% rename from apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java rename to apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java index 0f8ddcc815..83e512ccb7 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequest.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java @@ -1,6 +1,7 @@ package org.sagebionetworks.challenge.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; import io.swagger.v3.oas.annotations.media.Schema; import java.util.*; import java.util.Objects; @@ -8,17 +9,18 @@ import javax.validation.Valid; import javax.validation.constraints.*; -/** UserUpdateRequest */ +/** UserUpdateRequestDto */ +@JsonTypeName("UserUpdateRequest") @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @lombok.AllArgsConstructor @lombok.Builder @lombok.NoArgsConstructor -public class UserUpdateRequest { +public class UserUpdateRequestDto { @JsonProperty("status") - private UserStatus status; + private UserStatusDto status; - public UserUpdateRequest status(UserStatus status) { + public UserUpdateRequestDto status(UserStatusDto status) { this.status = status; return this; } @@ -30,11 +32,11 @@ public UserUpdateRequest status(UserStatus status) { */ @Valid @Schema(name = "status", required = false) - public UserStatus getStatus() { + public UserStatusDto getStatus() { return status; } - public void setStatus(UserStatus status) { + public void setStatus(UserStatusDto status) { this.status = status; } @@ -46,7 +48,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - UserUpdateRequest userUpdateRequest = (UserUpdateRequest) o; + UserUpdateRequestDto userUpdateRequest = (UserUpdateRequestDto) o; return Objects.equals(this.status, userUpdateRequest.status); } @@ -58,7 +60,7 @@ public int hashCode() { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("class UserUpdateRequest {\n"); + sb.append("class UserUpdateRequestDto {\n"); sb.append(" status: ").append(toIndentedString(status)).append("\n"); sb.append("}"); return sb.toString(); diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java index ac30be248e..82004e8716 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/entity/UserEntity.java @@ -12,7 +12,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import org.sagebionetworks.challenge.model.dto.UserStatus; +import org.sagebionetworks.challenge.model.dto.UserStatusDto; /** * The User information saved to DB. @@ -40,5 +40,5 @@ public class UserEntity { @Enumerated(EnumType.STRING) @Column(nullable = false) - private UserStatus status; + private UserStatusDto status; } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java index bd125d942e..2b8bb930c8 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/mapper/UserMapper.java @@ -1,13 +1,13 @@ package org.sagebionetworks.challenge.model.mapper; -import org.sagebionetworks.challenge.model.dto.User; +import org.sagebionetworks.challenge.model.dto.UserDto; import org.sagebionetworks.challenge.model.entity.UserEntity; import org.sagebionetworks.challenge.util.model.mapper.BaseMapper; import org.springframework.beans.BeanUtils; -public class UserMapper extends BaseMapper { +public class UserMapper extends BaseMapper { @Override - public UserEntity convertToEntity(User dto, Object... args) { + public UserEntity convertToEntity(UserDto dto, Object... args) { UserEntity userEntity = new UserEntity(); if (dto != null) { BeanUtils.copyProperties(dto, userEntity); @@ -16,8 +16,8 @@ public UserEntity convertToEntity(User dto, Object... args) { } @Override - public User convertToDto(UserEntity entity, Object... args) { - User user = new User(); + public UserDto convertToDto(UserEntity entity, Object... args) { + UserDto user = new UserDto(); if (entity != null) { BeanUtils.copyProperties(entity, user); } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java index 039798c677..bc0dab171a 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java @@ -11,9 +11,9 @@ import org.sagebionetworks.challenge.exception.GlobalErrorCode; import org.sagebionetworks.challenge.exception.InvalidUserException; import org.sagebionetworks.challenge.exception.UserAlreadyRegisteredException; -import org.sagebionetworks.challenge.model.dto.User; -import org.sagebionetworks.challenge.model.dto.UserStatus; -import org.sagebionetworks.challenge.model.dto.UserUpdateRequest; +import org.sagebionetworks.challenge.model.dto.UserDto; +import org.sagebionetworks.challenge.model.dto.UserStatusDto; +import org.sagebionetworks.challenge.model.dto.UserUpdateRequestDto; import org.sagebionetworks.challenge.model.entity.UserEntity; import org.sagebionetworks.challenge.model.mapper.UserMapper; import org.sagebionetworks.challenge.model.repository.UserRepository; @@ -32,7 +32,7 @@ public class UserService { private UserMapper userMapper = new UserMapper(); - public User createUser(User user) { + public UserDto createUser(UserDto user) { if (keycloakUserService.getUserByUsername(user.getUsername()).isPresent()) { throw new UserAlreadyRegisteredException( "This username is already registered.", GlobalErrorCode.ERROR_USERNAME_REGISTERED); @@ -55,7 +55,7 @@ public User createUser(User user) { Optional representation = keycloakUserService.getUserByUsername(user.getUsername()); user.setAuthId(representation.get().getId()); - user.setStatus(UserStatus.PENDING); + user.setStatus(UserStatusDto.PENDING); UserEntity userEntity = userRepository.save(userMapper.convertToEntity(user)); return userMapper.convertToDto(userEntity); } @@ -64,9 +64,9 @@ public User createUser(User user) { "Unable to create the new user", GlobalErrorCode.ERROR_INVALID_USER); } - public List listUsers(Pageable pageable) { + public List listUsers(Pageable pageable) { // Page allUsersInDb = userRepository.findAll(pageable); - List users = new ArrayList<>(); + List users = new ArrayList<>(); // List users = userMapper.convertToDtoList(allUsersInDb.getContent()); // users.forEach( // user -> { @@ -77,15 +77,15 @@ public List listUsers(Pageable pageable) { return users; } - public User getUser(Long userId) { + public UserDto getUser(Long userId) { return userMapper.convertToDto( userRepository.findById(userId).orElseThrow(EntityNotFoundException::new)); } - public User updateUser(Long id, UserUpdateRequest userUpdateRequest) { + public UserDto updateUser(Long id, UserUpdateRequestDto userUpdateRequest) { UserEntity userEntity = userRepository.findById(id).orElseThrow(EntityNotFoundException::new); - if (userUpdateRequest.getStatus() == UserStatus.APPROVED) { + if (userUpdateRequest.getStatus() == UserStatusDto.APPROVED) { UserRepresentation userRepresentation = keycloakUserService.getUser(userEntity.getAuthId()); userRepresentation.setEnabled(true); userRepresentation.setEmailVerified(true); diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index ca523751ae..788b8f7eef 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -148,8 +148,6 @@ components: - '@lombok.Builder' - '@lombok.NoArgsConstructor' UserUpdateRequest: - example: - status: PENDING properties: status: $ref: '#/components/schemas/UserStatus' From 2e22bdf1d4e1fd7576e2030fd4fd20b99f713a2c Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 23 Sep 2022 18:24:49 +0000 Subject: [PATCH 48/62] Minor update --- .../challenge/api/UserApiDelegateImpl.java | 16 ++++++------ .../challenge/service/UserService.java | 25 +++++++++++-------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index f1bc39f4bd..69245413de 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -1,9 +1,11 @@ package org.sagebionetworks.challenge.api; +import java.util.List; import lombok.extern.slf4j.Slf4j; import org.sagebionetworks.challenge.model.dto.UserDto; import org.sagebionetworks.challenge.service.UserService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -33,11 +35,11 @@ public ResponseEntity createUser(UserDto user) { return new ResponseEntity<>(HttpStatus.ACCEPTED); } - // @Override - // public ResponseEntity> listUsers(Pageable pageable) { - // log.info("List all the users"); - // log.info(pageable.toString()); - // // return new ResponseEntity<>(HttpStatus.ACCEPTED); - // return ResponseEntity.ok(userService.listUsers(pageable)); - // } + @Override + public ResponseEntity> listUsers(Pageable pageable) { + log.info("List all the users"); + log.info(pageable.toString()); + // return new ResponseEntity<>(HttpStatus.ACCEPTED); + return ResponseEntity.ok(userService.listUsers(pageable)); + } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java index bc0dab171a..afe40f3d23 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java @@ -1,6 +1,5 @@ package org.sagebionetworks.challenge.service; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -18,11 +17,12 @@ import org.sagebionetworks.challenge.model.mapper.UserMapper; import org.sagebionetworks.challenge.model.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Slf4j -// @RequiredArgsConstructor @Service public class UserService { @@ -64,16 +64,19 @@ public UserDto createUser(UserDto user) { "Unable to create the new user", GlobalErrorCode.ERROR_INVALID_USER); } + // TODO Return a page of Users + // See + // https://medium.com/devexperts/specification-first-make-life-easier-with-openapi-and-spring-eeaf5c22146b + @Transactional(readOnly = true) public List listUsers(Pageable pageable) { - // Page allUsersInDb = userRepository.findAll(pageable); - List users = new ArrayList<>(); - // List users = userMapper.convertToDtoList(allUsersInDb.getContent()); - // users.forEach( - // user -> { - // UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); - // user.setId(user.getId()); - // user.setEmail(userRepresentation.getEmail()); - // }); + Page allUsersInDb = userRepository.findAll(pageable); + List users = userMapper.convertToDtoList(allUsersInDb.getContent()); + users.forEach( + user -> { + UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); + user.setId(user.getId()); + user.setEmail(userRepresentation.getEmail()); + }); return users; } From 8b028b03fa2374047e79eb01f412633cef84b00c Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 23 Sep 2022 18:42:49 +0000 Subject: [PATCH 49/62] Refactor listUsers --- apps/challenge-user-service/openapitools.json | 5 +--- .../challenge/api/UserApiDelegateImpl.java | 26 ++++++++++++++++--- .../challenge/service/UserService.java | 20 +++++++------- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/apps/challenge-user-service/openapitools.json b/apps/challenge-user-service/openapitools.json index dd37e0e6cf..fc4764a86d 100644 --- a/apps/challenge-user-service/openapitools.json +++ b/apps/challenge-user-service/openapitools.json @@ -19,10 +19,7 @@ "library": "spring-boot", "modelPackage": "org.sagebionetworks.challenge.model.dto", "useTags": true, - "modelNameSuffix": "Dto", - "importMappings": { - "Pageable": "org.springframework.data.domain.Pageable" - } + "modelNameSuffix": "Dto" } } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index 69245413de..92f5d14fb0 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -1,11 +1,14 @@ package org.sagebionetworks.challenge.api; import java.util.List; +import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; +import org.sagebionetworks.challenge.model.dto.PageableDto; import org.sagebionetworks.challenge.model.dto.UserDto; +import org.sagebionetworks.challenge.model.mapper.UserMapper; import org.sagebionetworks.challenge.service.UserService; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.PageRequest; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -16,6 +19,8 @@ public class UserApiDelegateImpl implements UserApiDelegate { @Autowired UserService userService; + private UserMapper userMapper = new UserMapper(); + @Override public ResponseEntity createUser(UserDto user) { // getRequest() @@ -36,10 +41,25 @@ public ResponseEntity createUser(UserDto user) { } @Override - public ResponseEntity> listUsers(Pageable pageable) { + public ResponseEntity> listUsers(PageableDto pageable) { log.info("List all the users"); log.info(pageable.toString()); + List result = + userService + .listUsers(PageRequest.of(pageable.getPage(), pageable.getSize())) + .getContent() + .stream() + .map(userMapper::convertToDto) + .collect(Collectors.toList()); + return new ResponseEntity<>(result, HttpStatus.OK); // return new ResponseEntity<>(HttpStatus.ACCEPTED); - return ResponseEntity.ok(userService.listUsers(pageable)); + // return ResponseEntity.ok(userService.listUsers(pageable)); } + + // List result = accountService.findAllAccounts(PageRequest.of(page, limit)) + // .getContent() + // .stream() + // .map(accountMapper::toDto) + // .collect(Collectors.toList()); + // return new ResponseEntity<>(result, HttpStatus.OK); } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java index afe40f3d23..de94c2498e 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java @@ -1,7 +1,6 @@ package org.sagebionetworks.challenge.service; import java.util.Collections; -import java.util.List; import java.util.Optional; import javax.persistence.EntityNotFoundException; import lombok.extern.slf4j.Slf4j; @@ -68,16 +67,17 @@ public UserDto createUser(UserDto user) { // See // https://medium.com/devexperts/specification-first-make-life-easier-with-openapi-and-spring-eeaf5c22146b @Transactional(readOnly = true) - public List listUsers(Pageable pageable) { + public Page listUsers(Pageable pageable) { Page allUsersInDb = userRepository.findAll(pageable); - List users = userMapper.convertToDtoList(allUsersInDb.getContent()); - users.forEach( - user -> { - UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); - user.setId(user.getId()); - user.setEmail(userRepresentation.getEmail()); - }); - return users; + return allUsersInDb; + // List users = userMapper.convertToDtoList(allUsersInDb.getContent()); + // users.forEach( + // user -> { + // UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); + // user.setId(user.getId()); + // user.setEmail(userRepresentation.getEmail()); + // }); + // return users; } public UserDto getUser(Long userId) { From 10c4e18ae033371036558b9e480b56b726186c0f Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 23 Sep 2022 21:43:15 +0000 Subject: [PATCH 50/62] =?UTF-8?q?Can=20fetch=20list=20of=20all=20users!=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api-spec/openapi.yaml | 8 +++---- .../challenge/api/UserApi.java | 24 ++++++++++++------- .../challenge/api/UserApiDelegate.java | 16 ++++++------- .../challenge/api/UserApiDelegateImpl.java | 14 +++-------- .../challenge/service/UserService.java | 23 ++++++++++++------ .../src/main/resources/openapi.yaml | 16 ++++++------- 6 files changed, 55 insertions(+), 46 deletions(-) diff --git a/apps/challenge-user-service/api-spec/openapi.yaml b/apps/challenge-user-service/api-spec/openapi.yaml index 7151329214..408472a306 100644 --- a/apps/challenge-user-service/api-spec/openapi.yaml +++ b/apps/challenge-user-service/api-spec/openapi.yaml @@ -32,7 +32,7 @@ paths: "200": description: OK content: - '*/*': + 'application/json': schema: $ref: '#/components/schemas/User' /api/v1/users/{id}: @@ -51,7 +51,7 @@ paths: "200": description: OK content: - '*/*': + 'application/json': schema: $ref: '#/components/schemas/User' patch: @@ -75,7 +75,7 @@ paths: "200": description: OK content: - '*/*': + 'application/json': schema: $ref: '#/components/schemas/User' /api/v1/users/: @@ -93,7 +93,7 @@ paths: "200": description: OK content: - '*/*': + 'application/json': schema: type: array items: diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java index b7c87629a7..ae694feadc 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApi.java @@ -45,13 +45,15 @@ default UserApiDelegate getDelegate() { responseCode = "200", description = "OK", content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + @Content( + mediaType = "application/json", + schema = @Schema(implementation = UserDto.class)) }) }) @RequestMapping( method = RequestMethod.POST, value = "/api/v1/users/register", - produces = {"*/*"}, + produces = {"application/json"}, consumes = {"application/json"}) default ResponseEntity createUser( @Parameter(name = "UserDto", description = "", required = true) @Valid @RequestBody @@ -73,13 +75,15 @@ default ResponseEntity createUser( responseCode = "200", description = "OK", content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + @Content( + mediaType = "application/json", + schema = @Schema(implementation = UserDto.class)) }) }) @RequestMapping( method = RequestMethod.GET, value = "/api/v1/users/{id}", - produces = {"*/*"}) + produces = {"application/json"}) default ResponseEntity getUser( @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id) { return getDelegate().getUser(id); @@ -99,13 +103,15 @@ default ResponseEntity getUser( responseCode = "200", description = "OK", content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + @Content( + mediaType = "application/json", + schema = @Schema(implementation = UserDto.class)) }) }) @RequestMapping( method = RequestMethod.GET, value = "/api/v1/users/", - produces = {"*/*"}) + produces = {"application/json"}) default ResponseEntity> listUsers( @Parameter(name = "pageable", description = "") @Valid PageableDto pageable) { return getDelegate().listUsers(pageable); @@ -126,13 +132,15 @@ default ResponseEntity> listUsers( responseCode = "200", description = "OK", content = { - @Content(mediaType = "*/*", schema = @Schema(implementation = UserDto.class)) + @Content( + mediaType = "application/json", + schema = @Schema(implementation = UserDto.class)) }) }) @RequestMapping( method = RequestMethod.PATCH, value = "/api/v1/users/{id}", - produces = {"*/*"}, + produces = {"application/json"}, consumes = {"application/json"}) default ResponseEntity updateUser( @Parameter(name = "id", description = "", required = true) @PathVariable("id") Long id, diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java index 38ce919d16..ec2df3b2a9 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegate.java @@ -34,10 +34,10 @@ default ResponseEntity createUser(UserDto userDto) { .ifPresent( request -> { for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) { - if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); + ApiUtil.setExampleResponse(request, "application/json", exampleString); break; } } @@ -57,10 +57,10 @@ default ResponseEntity getUser(Long id) { .ifPresent( request -> { for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) { - if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); + ApiUtil.setExampleResponse(request, "application/json", exampleString); break; } } @@ -80,10 +80,10 @@ default ResponseEntity> listUsers(PageableDto pageable) { .ifPresent( request -> { for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) { - if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); + ApiUtil.setExampleResponse(request, "application/json", exampleString); break; } } @@ -104,10 +104,10 @@ default ResponseEntity updateUser(Long id, UserUpdateRequestDto userUpd .ifPresent( request -> { for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) { - if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { + if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) { String exampleString = "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - ApiUtil.setExampleResponse(request, "*/*", exampleString); + ApiUtil.setExampleResponse(request, "application/json", exampleString); break; } } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index 92f5d14fb0..098cc8779f 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -1,11 +1,9 @@ package org.sagebionetworks.challenge.api; import java.util.List; -import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.sagebionetworks.challenge.model.dto.PageableDto; import org.sagebionetworks.challenge.model.dto.UserDto; -import org.sagebionetworks.challenge.model.mapper.UserMapper; import org.sagebionetworks.challenge.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; @@ -19,8 +17,6 @@ public class UserApiDelegateImpl implements UserApiDelegate { @Autowired UserService userService; - private UserMapper userMapper = new UserMapper(); - @Override public ResponseEntity createUser(UserDto user) { // getRequest() @@ -45,13 +41,9 @@ public ResponseEntity> listUsers(PageableDto pageable) { log.info("List all the users"); log.info(pageable.toString()); List result = - userService - .listUsers(PageRequest.of(pageable.getPage(), pageable.getSize())) - .getContent() - .stream() - .map(userMapper::convertToDto) - .collect(Collectors.toList()); - return new ResponseEntity<>(result, HttpStatus.OK); + userService.listUsers(PageRequest.of(pageable.getPage(), pageable.getSize())); + // return new ResponseEntity<>(result, HttpStatus.OK); + return ResponseEntity.ok(result); // return new ResponseEntity<>(HttpStatus.ACCEPTED); // return ResponseEntity.ok(userService.listUsers(pageable)); } diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java index de94c2498e..490b538b7e 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java @@ -1,6 +1,7 @@ package org.sagebionetworks.challenge.service; import java.util.Collections; +import java.util.List; import java.util.Optional; import javax.persistence.EntityNotFoundException; import lombok.extern.slf4j.Slf4j; @@ -63,13 +64,21 @@ public UserDto createUser(UserDto user) { "Unable to create the new user", GlobalErrorCode.ERROR_INVALID_USER); } - // TODO Return a page of Users - // See - // https://medium.com/devexperts/specification-first-make-life-easier-with-openapi-and-spring-eeaf5c22146b @Transactional(readOnly = true) - public Page listUsers(Pageable pageable) { - Page allUsersInDb = userRepository.findAll(pageable); - return allUsersInDb; + public List listUsers(Pageable pageable) { + Page userEntities = userRepository.findAll(pageable); + List users = userMapper.convertToDtoList(userEntities.getContent()); + log.info("plop"); + + // int a = allUsersInDb.getContent(); + // log.info("allUsersInDb: {}", allUsersInDb.getContent()); + // users.forEach( + // user -> { + // UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); + // user.setId(user.getId()); + // user.setEmail(userRepresentation.getEmail()); + // }); + // return allUsersInDb; // List users = userMapper.convertToDtoList(allUsersInDb.getContent()); // users.forEach( // user -> { @@ -77,7 +86,7 @@ public Page listUsers(Pageable pageable) { // user.setId(user.getId()); // user.setEmail(userRepresentation.getEmail()); // }); - // return users; + return users; } public UserDto getUser(Long userId) { diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index 788b8f7eef..cd395ac04b 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -29,14 +29,14 @@ paths: responses: "200": content: - '*/*': + application/json: schema: $ref: '#/components/schemas/User' description: OK tags: - User x-content-type: application/json - x-accepts: '*/*' + x-accepts: application/json x-tags: - tag: User /api/v1/users/{id}: @@ -54,13 +54,13 @@ paths: responses: "200": content: - '*/*': + application/json: schema: $ref: '#/components/schemas/User' description: OK tags: - User - x-accepts: '*/*' + x-accepts: application/json x-tags: - tag: User patch: @@ -83,14 +83,14 @@ paths: responses: "200": content: - '*/*': + application/json: schema: $ref: '#/components/schemas/User' description: OK tags: - User x-content-type: application/json - x-accepts: '*/*' + x-accepts: application/json x-tags: - tag: User /api/v1/users/: @@ -107,7 +107,7 @@ paths: responses: "200": content: - '*/*': + application/json: schema: items: $ref: '#/components/schemas/User' @@ -115,7 +115,7 @@ paths: description: OK tags: - User - x-accepts: '*/*' + x-accepts: application/json x-tags: - tag: User components: From 586a554e42496beb791e627b69a2c7e6ccedf502 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 23 Sep 2022 21:46:32 +0000 Subject: [PATCH 51/62] Cleanup --- .../challenge/api/UserApiDelegateImpl.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index 098cc8779f..35f3a69e37 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -39,19 +39,9 @@ public ResponseEntity createUser(UserDto user) { @Override public ResponseEntity> listUsers(PageableDto pageable) { log.info("List all the users"); - log.info(pageable.toString()); + // TODO Take into account pageable.getSort() List result = userService.listUsers(PageRequest.of(pageable.getPage(), pageable.getSize())); - // return new ResponseEntity<>(result, HttpStatus.OK); return ResponseEntity.ok(result); - // return new ResponseEntity<>(HttpStatus.ACCEPTED); - // return ResponseEntity.ok(userService.listUsers(pageable)); } - - // List result = accountService.findAllAccounts(PageRequest.of(page, limit)) - // .getContent() - // .stream() - // .map(accountMapper::toDto) - // .collect(Collectors.toList()); - // return new ResponseEntity<>(result, HttpStatus.OK); } From 4768946e59c86042a6575dd8f8dcfeca6e807999 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Mon, 26 Sep 2022 16:34:55 +0000 Subject: [PATCH 52/62] Add script to pull raw openapi templates --- .../v6.1.x/openapi2SpringBoot.mustache | 27 ++ .../templates/v6.1.x/pojo.mustache | 248 ++++++++++++++++++ .../tools/pull-templates.sh | 11 + 3 files changed, 286 insertions(+) create mode 100644 apps/challenge-user-service/templates/v6.1.x/openapi2SpringBoot.mustache create mode 100644 apps/challenge-user-service/templates/v6.1.x/pojo.mustache create mode 100755 apps/challenge-user-service/tools/pull-templates.sh diff --git a/apps/challenge-user-service/templates/v6.1.x/openapi2SpringBoot.mustache b/apps/challenge-user-service/templates/v6.1.x/openapi2SpringBoot.mustache new file mode 100644 index 0000000000..01725be2d2 --- /dev/null +++ b/apps/challenge-user-service/templates/v6.1.x/openapi2SpringBoot.mustache @@ -0,0 +1,27 @@ +package {{basePackage}}; + +{{#openApiNullable}} +import com.fasterxml.jackson.databind.Module; +import org.openapitools.jackson.nullable.JsonNullableModule; +{{/openApiNullable}} +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = {"{{basePackage}}", "{{apiPackage}}" , "{{configPackage}}"}) +public class OpenApiGeneratorApplication { + + public static void main(String[] args) { + SpringApplication.run(OpenApiGeneratorApplication.class, args); + } + +{{#openApiNullable}} + @Bean + public Module jsonNullableModule() { + return new JsonNullableModule(); + } +{{/openApiNullable}} + +} \ No newline at end of file diff --git a/apps/challenge-user-service/templates/v6.1.x/pojo.mustache b/apps/challenge-user-service/templates/v6.1.x/pojo.mustache new file mode 100644 index 0000000000..48e6d0faf8 --- /dev/null +++ b/apps/challenge-user-service/templates/v6.1.x/pojo.mustache @@ -0,0 +1,248 @@ +/** + * {{description}}{{^description}}{{classname}}{{/description}} + */ +{{>additionalModelTypeAnnotations}} +{{#description}} +{{#swagger1AnnotationLibrary}} +@ApiModel(description = "{{{description}}}") +{{/swagger1AnnotationLibrary}} +{{#swagger2AnnotationLibrary}} +@Schema({{#name}}name = "{{name}}", {{/name}}description = "{{{description}}}") +{{/swagger2AnnotationLibrary}} +{{/description}} +{{#discriminator}} +{{>typeInfoAnnotation}} +{{/discriminator}} +{{#jackson}} +{{#isClassnameSanitized}} +@JsonTypeName("{{name}}") +{{/isClassnameSanitized}} +{{/jackson}} +{{#withXml}} +{{>xmlAnnotation}} +{{/withXml}} +{{>generatedAnnotation}} +{{#vendorExtensions.x-class-extra-annotation}} +{{{vendorExtensions.x-class-extra-annotation}}} +{{/vendorExtensions.x-class-extra-annotation}} +public class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}{{^parent}}{{#hateoas}} extends RepresentationModel<{{classname}}> {{/hateoas}}{{/parent}}{{#vendorExtensions.x-implements}}{{#-first}} implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { +{{#serializableModel}} + + private static final long serialVersionUID = 1L; +{{/serializableModel}} + {{#vars}} + + {{#isEnum}} + {{^isContainer}} +{{>enumClass}} + {{/isContainer}} + {{#isContainer}} + {{#mostInnerItems}} +{{>enumClass}} + {{/mostInnerItems}} + {{/isContainer}} + {{/isEnum}} + {{#jackson}} + @JsonProperty("{{baseName}}") + {{#withXml}} + @JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{.}}", {{/xmlNamespace}}localName = "{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}") + {{/withXml}} + {{/jackson}} + {{#gson}} + @SerializedName("{{baseName}}") + {{/gson}} + {{#vendorExtensions.x-field-extra-annotation}} + {{{vendorExtensions.x-field-extra-annotation}}} + {{/vendorExtensions.x-field-extra-annotation}} + {{#isContainer}} + {{#useBeanValidation}}@Valid{{/useBeanValidation}} + {{#openApiNullable}} + private {{>nullableDataType}} {{name}} = {{#isNullable}}JsonNullable.undefined(){{/isNullable}}{{^isNullable}}{{#required}}{{{defaultValue}}}{{/required}}{{^required}}null{{/required}}{{/isNullable}}; + {{/openApiNullable}} + {{^openApiNullable}} + private {{>nullableDataType}} {{name}} = {{#required}}{{{defaultValue}}}{{/required}}{{^required}}null{{/required}}; + {{/openApiNullable}} + {{/isContainer}} + {{^isContainer}} + {{#isDate}} + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) + {{/isDate}} + {{#isDateTime}} + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + {{/isDateTime}} + {{#openApiNullable}} + private {{>nullableDataType}} {{name}}{{#isNullable}} = JsonNullable.undefined(){{/isNullable}}{{^isNullable}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{/isNullable}}; + {{/openApiNullable}} + {{^openApiNullable}} + private {{>nullableDataType}} {{name}}{{#isNullable}} = null{{/isNullable}}{{^isNullable}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{/isNullable}}; + {{/openApiNullable}} + {{/isContainer}} + {{/vars}} + {{#vars}} + + {{! begin feature: fluent setter methods }} + public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) { + {{#openApiNullable}} + this.{{name}} = {{#isNullable}}JsonNullable.of({{name}}){{/isNullable}}{{^isNullable}}{{name}}{{/isNullable}}; + {{/openApiNullable}} + {{^openApiNullable}} + this.{{name}} = {{name}}; + {{/openApiNullable}} + return this; + } + {{#isArray}} + + public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) { + {{#openApiNullable}} + {{^required}} + if (this.{{name}} == null{{#isNullable}} || !this.{{name}}.isPresent(){{/isNullable}}) { + this.{{name}} = {{#isNullable}}JsonNullable.of({{{defaultValue}}}){{/isNullable}}{{^isNullable}}{{{defaultValue}}}{{/isNullable}}; + } + {{/required}} + this.{{name}}{{#isNullable}}.get(){{/isNullable}}.add({{name}}Item); + {{/openApiNullable}} + {{^openApiNullable}} + if (this.{{name}} == null) { + this.{{name}} = {{{defaultValue}}}; + } + this.{{name}}.add({{name}}Item); + {{/openApiNullable}} + return this; + } + {{/isArray}} + {{#isMap}} + + public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) { + {{^required}} + if (this.{{name}} == null) { + this.{{name}} = {{{defaultValue}}}; + } + {{/required}} + this.{{name}}.put(key, {{name}}Item); + return this; + } + {{/isMap}} + {{! end feature: fluent setter methods }} + {{! begin feature: getter and setter }} + + /** + {{#description}} + * {{{.}}} + {{/description}} + {{^description}} + * Get {{name}} + {{/description}} + {{#minimum}} + * minimum: {{.}} + {{/minimum}} + {{#maximum}} + * maximum: {{.}} + {{/maximum}} + * @return {{name}} + */ + {{#vendorExtensions.x-extra-annotation}} + {{{vendorExtensions.x-extra-annotation}}} + {{/vendorExtensions.x-extra-annotation}} + {{#useBeanValidation}} + {{>beanValidation}} + {{/useBeanValidation}} + {{#swagger2AnnotationLibrary}} + @Schema(name = "{{{baseName}}}", {{#isReadOnly}}accessMode = Schema.AccessMode.READ_ONLY, {{/isReadOnly}}{{#example}}example = "{{{.}}}", {{/example}}{{#description}}description = "{{{.}}}", {{/description}}required = {{{required}}}) + {{/swagger2AnnotationLibrary}} + {{#swagger1AnnotationLibrary}} + @ApiModelProperty({{#example}}example = "{{{.}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}{{#isReadOnly}}readOnly = {{{isReadOnly}}}, {{/isReadOnly}}value = "{{{description}}}") + {{/swagger1AnnotationLibrary}} + public {{>nullableDataType}} {{getter}}() { + return {{name}}; + } + + {{#vendorExtensions.x-setter-extra-annotation}} + {{{vendorExtensions.x-setter-extra-annotation}}} + {{/vendorExtensions.x-setter-extra-annotation}} + public void {{setter}}({{>nullableDataType}} {{name}}) { + this.{{name}} = {{name}}; + } + {{! end feature: getter and setter }} + {{/vars}} + {{#parentVars}} + + {{! begin feature: fluent setter methods for inherited properties }} + public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) { + super.{{setter}}({{name}}); + return this; + } + {{#isArray}} + + public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) { + super.add{{nameInCamelCase}}Item({{name}}Item); + return this; + } + {{/isArray}} + {{#isMap}} + + public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) { + super.put{{nameInCamelCase}}Item({{name}}Item); + return this; + } + {{/isMap}} + {{! end feature: fluent setter methods for inherited properties }} + {{/parentVars}} + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + }{{#hasVars}} + {{classname}} {{classVarName}} = ({{classname}}) o; + return {{#vars}}{{#vendorExtensions.x-is-jackson-optional-nullable}}equalsNullable(this.{{name}}, {{classVarName}}.{{name}}){{/vendorExtensions.x-is-jackson-optional-nullable}}{{^vendorExtensions.x-is-jackson-optional-nullable}}{{#isByteArray}}Arrays{{/isByteArray}}{{^isByteArray}}Objects{{/isByteArray}}.equals(this.{{name}}, {{classVarName}}.{{name}}){{/vendorExtensions.x-is-jackson-optional-nullable}}{{^-last}} && + {{/-last}}{{/vars}}{{#parent}} && + super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}} + return true;{{/hasVars}} + } + {{#vendorExtensions.x-jackson-optional-nullable-helpers}} + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + {{/vendorExtensions.x-jackson-optional-nullable-helpers}} + + @Override + public int hashCode() { + return Objects.hash({{#vars}}{{#vendorExtensions.x-is-jackson-optional-nullable}}hashCodeNullable({{name}}){{/vendorExtensions.x-is-jackson-optional-nullable}}{{^vendorExtensions.x-is-jackson-optional-nullable}}{{^isByteArray}}{{name}}{{/isByteArray}}{{#isByteArray}}Arrays.hashCode({{name}}){{/isByteArray}}{{/vendorExtensions.x-is-jackson-optional-nullable}}{{^-last}}, {{/-last}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}}); + } + {{#vendorExtensions.x-jackson-optional-nullable-helpers}} + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + {{/vendorExtensions.x-jackson-optional-nullable-helpers}} + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class {{classname}} {\n"); + {{#parent}} + sb.append(" ").append(toIndentedString(super.toString())).append("\n"); + {{/parent}} + {{#vars}}sb.append(" {{name}}: ").append(toIndentedString({{name}})).append("\n"); + {{/vars}}sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/apps/challenge-user-service/tools/pull-templates.sh b/apps/challenge-user-service/tools/pull-templates.sh new file mode 100755 index 0000000000..85040d8688 --- /dev/null +++ b/apps/challenge-user-service/tools/pull-templates.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +openapiGeneratorVersion="6.1.x" +destinationFolder="${PWD}/templates/v${openapiGeneratorVersion}" + +mkdir -p "${destinationFolder}" + +curl -O --output-dir "${destinationFolder}" \ + "https://raw.githubusercontent.com/OpenAPITools/openapi-generator/${openapiGeneratorVersion}/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/openapi2SpringBoot.mustache" +curl -O --output-dir "${destinationFolder}" \ + "https://raw.githubusercontent.com/OpenAPITools/openapi-generator/${openapiGeneratorVersion}/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache" \ No newline at end of file From ca0a72fb2b1a0e2858aed4f7f13ab3a6a7cae51b Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Mon, 26 Sep 2022 17:39:00 +0000 Subject: [PATCH 53/62] Fix schema name (#732) --- .gitignore | 1 + apps/challenge-user-service/api-spec/openapi.yaml | 4 ++++ .../org/sagebionetworks/challenge/model/dto/PageableDto.java | 3 ++- .../java/org/sagebionetworks/challenge/model/dto/UserDto.java | 3 ++- .../sagebionetworks/challenge/model/dto/UserStatusDto.java | 2 +- .../challenge/model/dto/UserUpdateRequestDto.java | 3 ++- apps/challenge-user-service/src/main/resources/openapi.yaml | 4 ++++ 7 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index d40b579d51..a8a1d68693 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ !.yarn/versions apps/challenge-user-service-2 apps/challengebot2 +apps/challenge-bot # See http://help.github.com/ignore-files/ for more about ignoring files. .coveralls.yml diff --git a/apps/challenge-user-service/api-spec/openapi.yaml b/apps/challenge-user-service/api-spec/openapi.yaml index 408472a306..339a215907 100644 --- a/apps/challenge-user-service/api-spec/openapi.yaml +++ b/apps/challenge-user-service/api-spec/openapi.yaml @@ -101,6 +101,7 @@ paths: components: schemas: User: + description: "TODO Add schema description" type: object properties: id: @@ -121,6 +122,7 @@ components: - '@lombok.Builder' - '@lombok.NoArgsConstructor' UserUpdateRequest: + description: "TODO Add schema description" type: object properties: status: @@ -130,6 +132,7 @@ components: - '@lombok.Builder' - '@lombok.NoArgsConstructor' UserStatus: + description: "TODO Add schema description" type: string enum: - PENDING @@ -138,6 +141,7 @@ components: - BLACKLIST example: PENDING Pageable: + description: "TODO Add schema description" type: object properties: page: diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/PageableDto.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/PageableDto.java index f635b895b5..f99d240244 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/PageableDto.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/PageableDto.java @@ -11,7 +11,8 @@ import javax.validation.Valid; import javax.validation.constraints.*; -/** PageableDto */ +/** TODO Add schema description */ +@Schema(name = "Pageable", description = "TODO Add schema description") @JsonTypeName("Pageable") @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") // TODO Add x-java-class-annotations diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java index 708aeb0c8f..c4d07540c8 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserDto.java @@ -9,7 +9,8 @@ import javax.validation.Valid; import javax.validation.constraints.*; -/** UserDto */ +/** TODO Add schema description */ +@Schema(name = "User", description = "TODO Add schema description") @JsonTypeName("User") @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @lombok.AllArgsConstructor diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java index c0fc7fe505..4fd107e792 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserStatusDto.java @@ -6,7 +6,7 @@ import javax.annotation.Generated; import javax.validation.constraints.*; -/** Gets or Sets UserStatus */ +/** TODO Add schema description */ @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") public enum UserStatusDto { PENDING("PENDING"), diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java index 83e512ccb7..3393130e8c 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/model/dto/UserUpdateRequestDto.java @@ -9,7 +9,8 @@ import javax.validation.Valid; import javax.validation.constraints.*; -/** UserUpdateRequestDto */ +/** TODO Add schema description */ +@Schema(name = "UserUpdateRequest", description = "TODO Add schema description") @JsonTypeName("UserUpdateRequest") @Generated(value = "org.openapitools.codegen.languages.SpringCodegen") @lombok.AllArgsConstructor diff --git a/apps/challenge-user-service/src/main/resources/openapi.yaml b/apps/challenge-user-service/src/main/resources/openapi.yaml index cd395ac04b..e4e2dd94ce 100644 --- a/apps/challenge-user-service/src/main/resources/openapi.yaml +++ b/apps/challenge-user-service/src/main/resources/openapi.yaml @@ -121,6 +121,7 @@ paths: components: schemas: User: + description: TODO Add schema description example: password: password id: 0 @@ -148,6 +149,7 @@ components: - '@lombok.Builder' - '@lombok.NoArgsConstructor' UserUpdateRequest: + description: TODO Add schema description properties: status: $ref: '#/components/schemas/UserStatus' @@ -157,6 +159,7 @@ components: - '@lombok.Builder' - '@lombok.NoArgsConstructor' UserStatus: + description: TODO Add schema description enum: - PENDING - APPROVED @@ -165,6 +168,7 @@ components: example: PENDING type: string Pageable: + description: TODO Add schema description properties: page: default: 0 From f2bbb27773db0d9061c29bc79420ecd4e1524e1f Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Mon, 26 Sep 2022 20:30:20 +0000 Subject: [PATCH 54/62] Update listUsers --- .../challenge/service/UserService.java | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java index 490b538b7e..98bd362029 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java @@ -32,6 +32,7 @@ public class UserService { private UserMapper userMapper = new UserMapper(); + // TODO Review this function public UserDto createUser(UserDto user) { if (keycloakUserService.getUserByUsername(user.getUsername()).isPresent()) { throw new UserAlreadyRegisteredException( @@ -68,32 +69,22 @@ public UserDto createUser(UserDto user) { public List listUsers(Pageable pageable) { Page userEntities = userRepository.findAll(pageable); List users = userMapper.convertToDtoList(userEntities.getContent()); - log.info("plop"); - - // int a = allUsersInDb.getContent(); - // log.info("allUsersInDb: {}", allUsersInDb.getContent()); - // users.forEach( - // user -> { - // UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); - // user.setId(user.getId()); - // user.setEmail(userRepresentation.getEmail()); - // }); - // return allUsersInDb; - // List users = userMapper.convertToDtoList(allUsersInDb.getContent()); - // users.forEach( - // user -> { - // UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); - // user.setId(user.getId()); - // user.setEmail(userRepresentation.getEmail()); - // }); + users.forEach( + user -> { + UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); + user.setId(user.getId()); + user.setEmail(userRepresentation.getEmail()); + }); return users; } + // TODO Review this function public UserDto getUser(Long userId) { return userMapper.convertToDto( userRepository.findById(userId).orElseThrow(EntityNotFoundException::new)); } + // TODO Review this function public UserDto updateUser(Long id, UserUpdateRequestDto userUpdateRequest) { UserEntity userEntity = userRepository.findById(id).orElseThrow(EntityNotFoundException::new); From 877e28c28718f1379d1c527eb01246d7809e7eca Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Mon, 26 Sep 2022 20:48:50 +0000 Subject: [PATCH 55/62] Restore actuator --- .../src/main/resources/application.yml | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/challenge-user-service/src/main/resources/application.yml b/apps/challenge-user-service/src/main/resources/application.yml index e4b4ad1d7d..fa1b384b99 100644 --- a/apps/challenge-user-service/src/main/resources/application.yml +++ b/apps/challenge-user-service/src/main/resources/application.yml @@ -26,18 +26,21 @@ server: # instance: # preferIpAddress: true -# management: -# info: -# env: -# enabled: true -# endpoints: -# web: -# exposure: -# include: info +management: + info: + env: + enabled: true + endpoints: + web: + exposure: + include: info,health + # endpoint: + # health: + # show-details: always -# info: -# application: -# name: ${spring.application.name} +info: + application: + name: ${spring.application.name} keycloak: realm: test @@ -69,6 +72,3 @@ app: # path: /api/v1/api-docs/openapi.json # packagesToScan: org.sagebionetworks.challenge.controller # pathsToMatch: /** - -# example: -# firstProperty: "main" From f928d8a15d5e3d97a4c3cf5c098aa9f894f49689 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Mon, 26 Sep 2022 21:43:32 +0000 Subject: [PATCH 56/62] Cleanup --- apps/challenge-user-service/src/main/resources/application.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/challenge-user-service/src/main/resources/application.yml b/apps/challenge-user-service/src/main/resources/application.yml index fa1b384b99..e8f9c9a0db 100644 --- a/apps/challenge-user-service/src/main/resources/application.yml +++ b/apps/challenge-user-service/src/main/resources/application.yml @@ -34,9 +34,6 @@ management: web: exposure: include: info,health - # endpoint: - # health: - # show-details: always info: application: From bca810f00c7bdd82dbac2725e7f5f4a733a8abe8 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Mon, 26 Sep 2022 21:51:25 +0000 Subject: [PATCH 57/62] Add method to get one user --- .../sagebionetworks/challenge/api/UserApiDelegateImpl.java | 6 +++++- .../org/sagebionetworks/challenge/service/UserService.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index 35f3a69e37..df1235202b 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -36,9 +36,13 @@ public ResponseEntity createUser(UserDto user) { return new ResponseEntity<>(HttpStatus.ACCEPTED); } + @Override + public ResponseEntity getUser(Long id) { + return ResponseEntity.ok(userService.getUser(id)); + } + @Override public ResponseEntity> listUsers(PageableDto pageable) { - log.info("List all the users"); // TODO Take into account pageable.getSort() List result = userService.listUsers(PageRequest.of(pageable.getPage(), pageable.getSize())); diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java index 98bd362029..c0355f57e6 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java @@ -78,7 +78,7 @@ public List listUsers(Pageable pageable) { return users; } - // TODO Review this function + @Transactional(readOnly = true) public UserDto getUser(Long userId) { return userMapper.convertToDto( userRepository.findById(userId).orElseThrow(EntityNotFoundException::new)); From c201f36b46f073f3af377843eacc7d7ce1055c9a Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Mon, 26 Sep 2022 22:01:26 +0000 Subject: [PATCH 58/62] Configure Eureka client --- .../src/main/resources/application.yml | 2 +- apps/challenge-user-service/build.gradle | 1 + .../challenge/ChallengeUserServiceApplication.java | 2 ++ .../src/main/resources/application.yml | 13 ++++++------- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/challenge-api-gateway/src/main/resources/application.yml b/apps/challenge-api-gateway/src/main/resources/application.yml index 414b4e83e8..6bce496723 100644 --- a/apps/challenge-api-gateway/src/main/resources/application.yml +++ b/apps/challenge-api-gateway/src/main/resources/application.yml @@ -6,7 +6,7 @@ app: spring: application: - name: challenge_api_gateway + name: challenge-api-gateway security: oauth2: client: diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index 80e26d561c..f792126d03 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -39,6 +39,7 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-validation:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" + implementation "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:${springCloudVersion}" implementation "org.springframework.data:spring-data-commons:${springDataVersion}" runtimeOnly 'mysql:mysql-connector-java:8.0.30' testImplementation "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java index 3dc5344f3b..37a1c03780 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java @@ -4,9 +4,11 @@ import org.openapitools.jackson.nullable.JsonNullableModule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; +@EnableEurekaClient @SpringBootApplication @ComponentScan( basePackages = { diff --git a/apps/challenge-user-service/src/main/resources/application.yml b/apps/challenge-user-service/src/main/resources/application.yml index e8f9c9a0db..36ed66f1b3 100644 --- a/apps/challenge-user-service/src/main/resources/application.yml +++ b/apps/challenge-user-service/src/main/resources/application.yml @@ -18,13 +18,12 @@ spring: server: port: 8083 -# eureka: -# client: -# service-url: -# # defaultZone: ${service.registry.url} -# defaultZone: http://challenge-service-registry:8081/eureka -# instance: -# preferIpAddress: true +eureka: + client: + service-url: + defaultZone: ${service.registry.url} + instance: + preferIpAddress: true management: info: From 6b45c08b7d44f566477aa47c582ca99111cb4c19 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Mon, 26 Sep 2022 22:20:52 +0000 Subject: [PATCH 59/62] Configure security but allow all requests for now --- apps/challenge-user-service/build.gradle | 1 + .../ChallengeUserServiceApplication.java | 3 +- .../configuration/SecurityConfiguration.java | 72 +++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SecurityConfiguration.java diff --git a/apps/challenge-user-service/build.gradle b/apps/challenge-user-service/build.gradle index f792126d03..76401678c5 100644 --- a/apps/challenge-user-service/build.gradle +++ b/apps/challenge-user-service/build.gradle @@ -37,6 +37,7 @@ dependencies { implementation "org.springframework.boot:spring-boot-devtools:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}" + implementation "org.springframework.boot:spring-boot-starter-security:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-validation:${springBootVersion}" implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" implementation "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:${springCloudVersion}" diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java index 37a1c03780..418b9ae29e 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/ChallengeUserServiceApplication.java @@ -4,11 +4,10 @@ import org.openapitools.jackson.nullable.JsonNullableModule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; -@EnableEurekaClient +// @EnableEurekaClient @SpringBootApplication @ComponentScan( basePackages = { diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SecurityConfiguration.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SecurityConfiguration.java new file mode 100644 index 0000000000..c56c9ed7be --- /dev/null +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/configuration/SecurityConfiguration.java @@ -0,0 +1,72 @@ +package org.sagebionetworks.challenge.configuration; + +import org.keycloak.adapters.springsecurity.KeycloakConfiguration; +import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; +import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; +import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; +import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; + +@KeycloakConfiguration +@EnableGlobalMethodSecurity(jsr250Enabled = true) +class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter { + + // @Autowired + // RestAccessDeniedHandler restAccessDeniedHandler; + + // @Autowired + // CustomKeycloakAuthenticationHandler customKeycloakAuthenticationHandler; + + @Override + protected void configure(HttpSecurity http) throws Exception { + super.configure(http); + http.csrf() + .disable() + .cors() + .disable() + .authorizeRequests() + // .antMatchers("/api/v1/users/register", "/api/v1/**", "/swagger-ui/**", + // "/swagger-ui.html") + .antMatchers("**") + .permitAll() + .anyRequest() + .authenticated(); + + // Custom error handler + // http.exceptionHandling().accessDeniedHandler(restAccessDeniedHandler); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + KeycloakAuthenticationProvider keycloakAuthenticationProvider = + keycloakAuthenticationProvider(); + keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); + auth.authenticationProvider(keycloakAuthenticationProvider); + } + + @Bean + @Override + protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { + return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); + } + + // // Keycloak auth exception handler + // @Bean + // @Override + // protected KeycloakAuthenticationProcessingFilter + // keycloakAuthenticationProcessingFilter() + // throws Exception { + // KeycloakAuthenticationProcessingFilter filter = + // new KeycloakAuthenticationProcessingFilter(this.authenticationManagerBean()); + // filter.setSessionAuthenticationStrategy(this.sessionAuthenticationStrategy()); + // filter.setAuthenticationFailureHandler(customKeycloakAuthenticationHandler); + // return filter; + // } + +} From c5e3d3535277f295dc8b5355e4dac840d0bc3121 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Tue, 27 Sep 2022 16:50:45 +0000 Subject: [PATCH 60/62] Can now register user --- .../challenge/api/UserApiDelegateImpl.java | 19 ++----------------- .../challenge/service/UserService.java | 11 +++++++---- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java index df1235202b..3e74d3fdd6 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/api/UserApiDelegateImpl.java @@ -7,7 +7,6 @@ import org.sagebionetworks.challenge.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -18,22 +17,8 @@ public class UserApiDelegateImpl implements UserApiDelegate { @Autowired UserService userService; @Override - public ResponseEntity createUser(UserDto user) { - // getRequest() - // .ifPresent( - // request -> { - // for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) - // { - // if (mediaType.isCompatibleWith(MediaType.valueOf("*/*"))) { - // String exampleString = - // "{ \"password\" : \"password\", \"id\" : 0, \"email\" : \"email\", - // \"authId\" : \"authId\", \"username\" : \"username\", \"status\" : \"PENDING\" }"; - // ApiUtil.setExampleResponse(request, "*/*", exampleString); - // break; - // } - // } - // }); - return new ResponseEntity<>(HttpStatus.ACCEPTED); + public ResponseEntity createUser(UserDto userDto) { + return ResponseEntity.ok(userService.createUser(userDto)); } @Override diff --git a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java index c0355f57e6..50c411664a 100644 --- a/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java +++ b/apps/challenge-user-service/src/main/java/org/sagebionetworks/challenge/service/UserService.java @@ -32,7 +32,7 @@ public class UserService { private UserMapper userMapper = new UserMapper(); - // TODO Review this function + @Transactional public UserDto createUser(UserDto user) { if (keycloakUserService.getUserByUsername(user.getUsername()).isPresent()) { throw new UserAlreadyRegisteredException( @@ -72,7 +72,6 @@ public List listUsers(Pageable pageable) { users.forEach( user -> { UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); - user.setId(user.getId()); user.setEmail(userRepresentation.getEmail()); }); return users; @@ -80,8 +79,12 @@ public List listUsers(Pageable pageable) { @Transactional(readOnly = true) public UserDto getUser(Long userId) { - return userMapper.convertToDto( - userRepository.findById(userId).orElseThrow(EntityNotFoundException::new)); + UserDto user = + userMapper.convertToDto( + userRepository.findById(userId).orElseThrow(EntityNotFoundException::new)); + UserRepresentation userRepresentation = keycloakUserService.getUser(user.getAuthId()); + user.setEmail(userRepresentation.getEmail()); + return user; } // TODO Review this function From 1df2f6c41ec3a38f8a1ff20f3548ac9d50569e2a Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Tue, 27 Sep 2022 17:02:46 +0000 Subject: [PATCH 61/62] Rename session.sql --- .../{playground.session.sql => session.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/challenge-user-service/{playground.session.sql => session.sql} (100%) diff --git a/apps/challenge-user-service/playground.session.sql b/apps/challenge-user-service/session.sql similarity index 100% rename from apps/challenge-user-service/playground.session.sql rename to apps/challenge-user-service/session.sql From 8e0360a73e5484b57962babc12949719cdf6832a Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Tue, 27 Sep 2022 21:25:45 +0000 Subject: [PATCH 62/62] Update `.gitignore` --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index a8a1d68693..58a5f1beb2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,6 @@ !.yarn/plugins !.yarn/sdks !.yarn/versions -apps/challenge-user-service-2 -apps/challengebot2 -apps/challenge-bot # See http://help.github.com/ignore-files/ for more about ignoring files. .coveralls.yml